Skip to content
字数
812 字
阅读时间
4 分钟

references

《整体代码 script》为何是宏任务

[[async+await 和 for 循环]]

task queue 任务队列

JS 在处理任务的时候,可以分为同步任务和异步任务

只有当同步任务都执行完毕之后,才会到任务队列里面执行异步任务

Js 中,有两类任务队列:宏任务队列(macro tasks)和微任务队列(micro tasks)。宏任务队列可以有多个,微任务队列只有一个。

宏任务:script(全局任务), setTimeout, setInterval, setImmediate, I/O, UI rendering.
微任务:promise 的回调, Object.observe,node 中的 process.nextTick 、对 Dom 变化监听的 MutationObserver. await 后面的语句

1、js 的执行顺序,先同步后异步
2、异步中任务队列的执行顺序: 先微任务 microtask 队列,再宏任务 macrotask 队列
3、调用 Promise 中的 resolve,reject 属于微任务队列,setTimeout 属于宏任务队列

注意以上都是 队列先进先出

为什么要分宏任务和微任务

为了给紧急任务一个插队的机会,否则新入队的任务永远被放在队尾

event loop -- 浏览器环境

事件循环:JS 代码执行过程中所有任务(事件)的调度的先后顺序

执行机制:

  1. 所有同步任务都在主线程上执行,形成一个执行栈(调用栈);
  2. 主线程之外,还存在一个 ' 任务队列 '(task queue),浏览器中的各种 Web API 为异步的代码提供了一个单独的运行空间,当异步的代码运行完毕以后,会将代码中的回调送入到 任务队列中(队列遵循先进先出得原则)
  3. 一旦主线程的栈中的所有同步任务执行完毕后,调用栈为空时系统就会将队列中的回调函数依次压入调用栈中执行,当调用栈为空时,仍然会不断循环检测任务队列中是否有代码需要执行;

运行过程:

  1. 主线程每次执行时,先看看要执行的是同步任务,还是异步的 API
  2. 同步任务就继续执行,一直执行完
  3. 遇到异步 API 就将它交给对应的异步线程,自己继续执行同步任务
  4. 异步线程执行异步 API,执行完后,将异步回调事件放入事件队列上
  5. 主线程手上的同步任务干完后就来事件队列看看有没有任务
  6. 主线程发现事件队列有任务,就取出里面的任务执行
  7. 主线程不断循环上述流程

参考

async await 与微任务

前端基本功(五):了解 javascript 的运行机制(单线程、任务队列、EventLoop、微任务、宏任务)

【JavaScript】《整体代码 script》为何是一个宏任务_iuukai 的博客-CSDN 博客_script 是宏任务

解释较全面: setTimeout 和 setImmediate 到底谁先执行,本文让你彻底理解 Event Loop - 掘金

贡献者

The avatar of contributor named as jiechen jiechen

页面历史

撰写