首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

任务异步还是同步?再谈事件循环

前言宏任务异步还是同步笔者最近在复习事件循环这个老生常谈的话题,看到有的文章提到“异步任务分为宏任务和微任务”,即宏任务属于异步任务。这和我理解的不太一样,于是决定重新梳理一遍事件循环。...先说我得出的结论:宏任务跟同步异步无关,可以是同步,也可以是异步,而微任务则全是异步。下面开始重头讲浏览器的事件循环,希望对各位看官老爷有帮助。举个栗子‍♀️关于事件循环有一个很不错的例子是早餐店。...在 JavaScript 开始运行的时候,所有同步代码会按书写顺序在调用栈中依次执行,而异步任务的回调函数则会被放入任务队列,等待执行。...异步任务:由于 setTimeout 是异步任务,因此它的回调函数被放入任务队列中,等待执行。即使它设置的延迟是 0 毫秒,也不会立即执行。...宏任务和微任务在上一节中,我们提到了同步任务异步任务。而在事件循环机制中,JavaScript 提供了另一种任务分类:宏任务和微任务

12310

破阵九解:Node和浏览器之事件循环任务队列异步顺序数据结构

>> 目录 开门见山:Node和浏览器的异步执行顺序问题 两种环境下的宏任务和微任务(macrotask && microtask) Node和浏览器的事件循环模型在实现层面的区别...,其中我们发现,有的异步API执行快,而有的异步API执行慢,实际上,它们作为异步任务,被分成了宏任务和微任务两大阵营,同时整体表现出微任务执行快于宏任务的现象 在宏任务和微任务方面,Node和浏览器也是差异很大的...>> Node的event loop Node的事件循环基于libuv实现,libuv是Node.js的底层依赖,一个跨平台的异步IO库。...Q6.其他微任务队列 保存Promise形成的任务 >> 主队列和中间队列的关系 在一轮循环中,4个主队列,每处理完一个主队列,接着就要把两个中间队列处理一次, 我的理解是:一趟循环走下来, 4个主队列都各自被处理了一次...process.nextTick: 将回调函数放入到队列中,在下一轮Tick时取出执行,可以达到setTimeout(fn,0)的效果,由于不需要动用红黑树,效率更高时间复杂度为O(1)。相比较之下。

1.2K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    JavaScript运行机制

    接下来我们通过两个例子说明同步任务异步任务的区别: console.log("A"); while(true){ } console.log("B"); 请问最后的输出结果是什么?...如果你的回答是A,恭喜你答对了,因为这是同步任务,程序由上到下执行,遇到while()死循环,下面语句就没办法执行。...哪些语句会放入异步任务队列及放入时机 一般来说,有以下四种会放入异步任务队列: 1.setTimeout和setlnterval 2.DOM事件 3.ES6中的Promise 4.Ajax异步请求...javascript 代码运行分两个阶段: 1、预解析---把所有的函数定义提前,所有的变量声明提前,变量的赋值不提前 2、执行---从上到下执行(按照js运行机制) 至于放入异步任务队列的时机,我们通过...for循环一次碰到一个 setTimeout(),并不是马上把setTimeout()拿到异步队列中,而要等到一秒后,才将其放到任务队列里面,一旦"执行栈"中的所有同步任务执行完毕(即for循环结束,此时

    72830

    JS中的同步异步编程,宏任务与微任务的执行顺序

    异步:在主栈中执行一个任务,但是发现这个任务是一个异步的操作,我们会把它移除主栈,放到等待任务队列中(此时浏览器会分配其它线程监听异步任务是否到达指定的执行时间),如果主栈执行完成,监听者会把到达时间的异步任务重新放到主栈中执行...'); let i = 0; while (i <= 99999999) { i++; } console.timeEnd('WHILE'); setTimeout(() => { console.log...我们先模拟下浏览器的程序执行过程,代码自上而下执行,碰到第一个程序,先放入主栈(主任务队列),此时浏览器发现这是一个宏任务定时器,把它移出主栈,放入等待任务队列,再继续执行下面的代码,放入主栈执行,发现第二个任务也是宏任务的定时器...,放入等待队列,继续往下执行,推入主栈,同步任务循环99999999次之后输出次数,再执行下一个程序,也移入等待队列,再执行代码,发现是同步任务,输出4,此时主栈空闲,任务队列到达时间后先进先出的原则...,首先第二个任务到达时间,把它放入主栈执行,输出2,此时本因输出3,因为第三个程序是10ms到达,第一个是20s到达,但是第三个程序是等待247.849853515625ms后才放入的等待队列,所以第一个程序先到达

    2K10

    js 定时器笔记

    本文是学习js定时器、单线程、同步异步任务的笔记,只适合初学者。...2、使用注意 推迟执行的代码必须以字符串的形式,放入setTimeout。 因为引擎内部使用eval函数,将字符串转为代码。 如果推迟执行的是函数,则可以直接将函数名,放入setTimeout。...解析:先执行主线程的for循环,for循环执行了10次,把匿名函数添加了到任务序列10次。...解析:因为while循环是在主线程执行,主线程的while循环不停止,是不会再执行任务队列里面setimeout的函数的。...等到同步任务全部执行完,就会去看任务队列里面的异步任务。如果满足条件,那么异步任务就重新进入主线程开始执行,这时它就变成同步任务了。等到执行完,下一个异步任务再进入主线程开始执行。

    7.3K60

    setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop

    特别是对于JS这种只有一个线程的语言,如果都像我们第一个例子那样去while(true),那浏览器就只有一直卡死了,只有等这个循环运行完才会有响应。...事件触发线程不仅会将定时器事件放入任务队列,其他满足条件的事件也是他负责放进任务队列。...所以JS异步的实现靠的就是浏览器的多线程,当他遇到异步API时,就将这个任务交给对应的线程,当这个异步API满足回调条件时,对应的线程又通过事件触发线程将这个事件放入任务队列,然后主线程从任务队列取出事件继续执行...,将异步回调事件放入事件队列上 主线程手上的同步任务干完后就来事件队列看看有没有任务 主线程发现事件队列有任务,就取出里面的任务执行 主线程不断循环上述流程 定时器不准 Event Loop的这个流程里面其实还是隐藏了一些坑的...不同的异步API对应不同的实现线程 异步线程与主线程通讯靠的是Event Loop 异步线程完成任务后将其放入任务队列 主线程不断轮询任务队列,拿出任务执行 任务队列有宏任务队列和微任务队列的区别 微任务队列的优先级更高

    98741

    Js异步机制的实现

    var i = 100; while(--i) { console.log(i); } console.log("while 执行完毕我才能执行"); 异步 异步执行就是非阻塞模式执行,每一个任务有一个或多个回调函数...var i = 3000000000; while(--i) { } console.log("循环执行完毕"); 本地测试,设置的setTimeout回调函数大约在30s之后才执行,远远大于4ms...Js实现异步是通过一个执行栈与一个任务队列来完成异步操作的,所有同步任务都是在主线程上执行的,形成执行栈,任务队列中存放各种事件回调(也可以称作消息),当执行栈中的任务处理完成后,主线程就开始读取任务队列中的任务并执行...等操作 当Js执行时,进行如下流程 首先将执行栈中代码同步执行,将这些代码中异步任务加入后台线程中 执行栈中的同步代码执行完毕后,执行栈清空,并开始扫描微队列 取出微队列队首任务放入执行栈中执行,此时微队列是进行了出队操作...放入执行栈中执行,执行完毕后继续扫描微队列为空则扫描宏队列,出队执行 不断往复...

    2.8K20

    JS事件循环之宏任务和微任务

    异步任务:比如 ajax 网络请求,setTimeout 定时函数等都属于异步任务异步任务会通过任务队列(Event Queue)的机制(先进先出的机制)来进行协调。...以上不断重复的过程就叫做 Event Loop(事件循环)。 每一次的循环操作被称为tick。 ?...#总结 有个小 tip:从规范来看,microtask 优先于 task 执行,所以如果有需要优先执行的逻辑,放入 microtask 队列会比 task 更早的被执行。...最后的最后,记住,JavaScript 是一门单线程语言,异步操作都是放到事件循环队列里面,等待主执行栈来执行的,并没有专门的异步执行线程。 #参考 知乎-【JS】深入理解事件循环,这一篇就够了!...(必看) 掘金小册-前端性能优化-Event Loop 与异步更新策略 Segmentfault-译文:JS 事件循环机制(event loop)之宏任务、微任务 现代JavaScript-事件循环 这一次

    1.1K10

    「Nodejs进阶」一文吃透异步IO和事件循环

    然后异步调用的第一阶段就完成了,JavaScript 会继续往下执行执行栈上的代码逻辑,当前的 I/O 操作将以请求对象的形式放入到线程池中,等待执行。达到了异步 I/O 的目的。...第二阶段:形成的请求对象,会被放入线程池,如果线程池有空闲的 I/O 线程,会执行此次 I/O 任务,得到结果。...第三阶段:事件循环中 I/O 观察者,会从请求对象中找到已经得到结果的 I/O 请求对象,取出结果和回调函数,将回调函数放入事件循环中,执行回调,完成整个异步 I/O 任务。...const queue = [ ... ] // queue 里面放着待处理事件 while(true){ //开始循环 //执行 queue 中的任务 //.......while (r !

    2.1K20

    JavaScript同步、异步及事件循环

    同步、异步 JS是单线程的,每次只能做一件事情。像以下这种情况,代码会按顺序执行,这个就叫同步。...虽然JS是单线程,但是浏览器是多线程的,在遇到像setTimeout、DOM事件、ajax等这种任务时,会转交给浏览器的其他工作线程(上面提到的几个线程)执行,执行完之后将回调函数放入任务队列。...JS主线程,就像是一个while循环,会一直执行下去。在这期间,每次都会查看任务队列有没有需要执行的任务(回调函数)。在执行完一个任务之后,会继续下一个循环,直到任务队列所有任务都执行完为止。...,会开始执行宏任务队列 在执行完一个宏任务之后,跳出来,重新开始下一个循环(从1开始执行) 也就是说执行微任务队列 会将队列中的所有微任务执行完 而执行宏任务队列 每次只执行一个宏任务 然后重新开始下一个循环...then,加入微任务队列,宏任务执行完重新开始下一个循环

    1.2K30

    JavaScript事件循环模型

    当调用栈为空时,JavaScript 引擎会检查事件队列,如果队列中有任务,则将任务从队列中取出并放入调用栈中执行。这个过程不断循环,被称为事件循环。...当引擎遇到异步任务时,会将其委托给相应的 Web API 处理。一旦异步任务完成,Web API 会将回调函数放入事件队列中。4....事件循环(Event Loop)事件循环是 JavaScript 引擎的核心部分。它负责不断地检查调用栈和事件队列,当调用栈为空时,会从事件队列中取出任务放入调用栈中执行。...调用栈为空,事件循环开始。事件循环检查事件队列,发现定时器任务,将其放入调用栈中执行,输出 'Timeout'。定时器任务执行完成,调用栈为空,事件循环继续。...事件循环检查事件队列,发现 Promise 任务,将其放入调用栈中执行,输出 'Promise'。Promise 任务执行完成,调用栈为空,事件循环继续。事件循环检查事件队列,发现没有任务,结束。

    35820

    PHP-web框架Laravel-队列(一)

    队列是一种异步处理方式,可以将一些耗时的任务交给队列系统异步处理,从而让 Web 应用程序变得更加高效和稳定。...队列系统概述队列系统是一种异步处理任务的方式,将一些耗时的任务推入到队列中,让队列系统异步处理,从而不会影响 Web 应用程序的响应速度。...Laravel 队列系统基于以下三个核心组件:连接器(Connection):连接器定义了如何连接到队列后端,如何将消息推入队列,以及如何从队列中拉取消息。...sync 连接使用了同步驱动(sync driver),表示任务会同步执行,而不会放入队列中异步执行。...redis 连接使用了 Redis 驱动(redis driver),表示任务会被放入 Redis 队列中异步执行。

    77211

    # 一次搞懂 EventLoop

    异步任务:比如 ajax 网络请求,setTimeout 定时函数等都属于异步任务异步任务会通过任务队列(Event Queue)的机制(先进先出的机制)来进行协调。...所以 Javascript 是异步的,支持多个事件的并发,而 JavaScript 的并发模型基于“事件循环”。...在 Javascript 中,主线程从"任务队列"中读取事件,这个过程是循环不断的,整个的这种运行机制又称为 Event Loop(事件循环)。...# 总结 有个小 tip:从规范来看,microtask 优先于 task 执行,所以如果有需要优先执行的逻辑,放入 microtask 队列会比 task 更早的被执行。...最后的最后,记住,JavaScript 是一门单线程语言,异步操作都是放到事件循环队列里面,等待主执行栈来执行的,并没有专门的异步执行线程。 # 参考 知乎-【JS】深入理解事件循环,这一篇就够了!

    10310

    JavaScript执行(一):Promise里的代码为什么比setTimeout先执行?

    宏观和微观任务 JavaScript 引擎等待宿主环境分配宏观任务,在操作系统中,通常等待的行为都是一个事件循环,所以在 Node 术语中,也会把这个部分称为事件循环。...在底层的 C/C++ 代码中,这个事件循环是一个跑在独立线程中的循环,我们用伪代码来表示,大概是这样的: while(TRUE) { r = wait(); execute(r); }...我们可以大概理解:宏观任务的队列就相当于事件循环。...在宏观任务中,JavaScript 的 Promise 还会产生异步代码,JavaScript 必须保证这些异步代码在一个宏观任务中完成,因此,每个宏观任务中又包含了一个微观任务队列: 有了宏观任务和微观任务机制...foo,可以看到,如果我们把 sleep 这样的异步操作放入某一个框架或者库中,使用者几乎不需要了解 Promise 的概念即可进行异步编程了。

    59110

    JavaScript中Promise里的代码为什么比setTimeout先执行?

    宏观和微观任务 JavaScript 引擎等待宿主环境分配宏观任务,在操作系统中,通常等待的行为都是一个事件循环,所以在 Node 术语中,也会把这个部分称为事件循环。...在底层的 C/C++ 代码中,这个事件循环是一个跑在独立线程中的循环,我们用伪代码来表示,大概是这样的: while(TRUE) { r = wait(); execute(r); }...我们可以大概理解:宏观任务的队列就相当于事件循环。...在宏观任务中,JavaScript 的 Promise 还会产生异步代码,JavaScript 必须保证这些异步代码在一个宏观任务中完成,因此,每个宏观任务中又包含了一个微观任务队列: 有了宏观任务和微观任务机制...foo,可以看到,如果我们把 sleep 这样的异步操作放入某一个框架或者库中,使用者几乎不需要了解 Promise 的概念即可进行异步编程了。

    85420

    Python协程、异步IO与asyncio

    基本概念 异步IO的核心概念包括: 非阻塞IO:异步IO允许执行非阻塞的IO操作,这意味着程序在等待IO完成时不会被阻塞。 事件循环异步IO通常使用事件循环来管理协程和异步任务的调度。...事件循环负责将协程放入等待IO的队列,并在IO完成时恢复它们的执行。...(): # 将非阻塞IO操作放入事件循环中 task1 = asyncio.create_task(non_blocking_io_operation("task1")) task2...这些新增功能允许所谓的异步编程。 基本概念 asyncio库的基本概念包括: 事件循环(Event Loop):事件循环异步程序的核心,负责调度协程和处理异步任务的完成。...await关键字用于等待任务完成。 异步事件循环     事件循环是 asyncio 应用程序的核心,负责处理所有正在运行的任务。事件循环支持多任务处理。

    69930

    JavaScript EventLoop

    EventLoop 即事件循环机制,是指浏览器或 Node 的一种解决 JavaScript 单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。...如果有那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。...这个时候就会去任务队列中按照顺序读取一个任务放入到栈中执行。 每次栈内被清空,都会去读取任务队列有没有任务,有就读取执行,一直循环读取~执行的操作。...EventLoop 事件循环 介绍 主线程从“任务队列”中读取执行事件,这个过程是循环不断的,这个机制被称为事件循环。...异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中,等待主线程空闲的时候(调用栈被清空),被读取到栈内等待主线程的执行。

    17100
    领券