Event Loop、macrotask、micritask 的结论和参考

发布于 2021-12-03 23:05:24 字数 3271 浏览 1265 评论 0

Event Loop

JavaScript 是单线程的语言,为了处理一些耗时的任务,会将任务分布到主线程和任务队列中。

一旦主线程的所有任务执行完毕,就会读取任务队列里面的任务。

macrotask vs microtask

任务队列里的任务又分 macrotask 和 microtask,并且单独维护。

如果你需要在同步中进行异步任务,那么使用 microtask;否则就使用 macrotask。

  • macrotasks: setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering
  • microtasks: process.nextTick, Promises, Object.observe, MutationObserver

执行顺序

  1. 执行主线程的任务
  2. 遇到一些非立即执行的任务,分别放到 macrotask 和 microtask 队列中。
  3. 立即执行 microtask 中所有的任务。
  4. 开始执行 macrotask 中的第一个任务,并且可能继续产生新的任务。
  5. 如果 4 产生了 microtask,会继续执行 3。
  6. 接着 4 开始执行下一个 macrotask 任务。

执行示例

下面提供了 4 个例子,可以先自己推算下对不对,其中最后一个是需要在 node.js 环境中执行。

console.log(1);

setTimeout(() => {
  console.log(2);
})

setTimeout(() => {
  console.log(3);
})

new Promise((resolve)=>{
  console.log(4);
  resolve();
}).then(()=>{
  console.log(5);
})

// 1 4 5 2 3
console.log(1);

setTimeout(() => {
  console.log(2);
})

setTimeout(() => {
  console.log(3);
})

new Promise((resolve)=>{
  console.log(4);
  resolve();
}).then(()=>{
  console.log(5);
  new Promise((resolve) => {
    console.log(6);
    resolve();
  }).then(() => {
    console.log(7);
  })
})
// 1 4 5 6 7 2 3
console.log(1);
****
setTimeout(() => {
  console.log(2);
  new Promise((resolve) => {
    console.log(6);
    resolve();
  }).then(() => {
    console.log(7);
  })
})

setTimeout(() => {
  console.log(3);
})

new Promise((resolve)=>{
  console.log(4);
  resolve();
}).then(()=>{
  console.log(5);
})
// 1 4 5 2 6 7 3
console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

1 7 6 8 2 4 3 5 9 11 10

参考资料

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

挽清梦

暂无简介

0 文章
0 评论
595 人气
更多

推荐作者

一梦浮鱼

文章 0 评论 0

mb_Z9jVigFL

文章 0 评论 0

伴随着你

文章 0 评论 0

耳钉梦

文章 0 评论 0

18618447101

文章 0 评论 0

蜗牛

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文