JS宏任务与微任务
JS把异步任务分为宏任务与微任务。
- 在ES5之后,JavaScript引入了Promise,这样不需要浏览器,JavaScript引擎自身也能够发起异步任务了。
宏任务由宿主(浏览器、Node)发起
任务(代码) | 宏任务 | 环境 |
---|---|---|
script | 宏任务 | 浏览器 |
事件 | 宏任务 | 浏览器 |
网络请求(Ajax/Fetch) | 宏任务 | 浏览器 |
setTimeout()/setInterval() | 宏任务 | 浏览器 |
微任务JS引擎发起的任务
任务(代码) | 微任务 | 环境 |
---|---|---|
Promise的then | 微任务 | JS引擎 |
nextTick | 微任务 | JS引擎 |
await右结合和下方的代码 | 微任务 | JS引擎 |
Promise本身同步,then/catch的回调函数是异步的
代码分类
同步代码(js执行栈/回调栈)
微任务的异步代码(js引擎)
- process.nextTick (node)
- Promise.then catch()
- Async/Await
- Object.observe
宏任务的异步代码(宿主环境)
- script
- setTimeout/setInterval
- setImmediate
- IO
运行机制
运行顺序:同步>微任务>宏任务
在事件循环中,每进行一次循环操作称为 tick,每一次 tick 的任务处理模型是比较复杂的,但关键步骤如下:
一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。
- 同步代码先执行完
- 立即执行当前微任务队列中的所有微任务(依次执行)
- 执行一个宏任务(栈中没有就从事件队列中获取)
- 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
- 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
- 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
- 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
面试题目讲解可以参考视频:https://www.bilibili.com/video/BV1G84y1B7hZ?vd_source=5053a6dbc1b42e83bb14303fbfead9a2
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 学途路漫漫!