极客时间返利平台,你可以在上边通过山月的链接购买课程,并添加我的微信 (shanyue94) 领取返现。

# JS 中异步任务为何分为微任务与宏任务

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 686 (opens new window)

TODO

Author

回答者: CheckLee (opens new window)

转一下知乎的回答。 为了插队。 一个 Event Loop,Microtask 是在 Macrotask 之后调用,Microtask 会在下一个 Event Loop 之前执行调用完,并且其中会将 Microtask 执行当中新注册的 Microtask 一并调用执行完,然后才开始下一次 Event loop,所以如果有新的 Macrotask 就需要一直等待,等到上一个 Event loop 当中 Microtask 被清空为止。 由此可见, 我们可以在下一次 Event loop 之前进行插队。如果不区分 Microtask 和 Macrotask,那就无法在下一次 Event loop 之前进行插队,其中新注册的任务得等到下一个 Macrotask 完成之后才能进行,这中间可能你需要的状态就无法在下一个 Macrotask 中得到同步。状态的同步对于视图来说至关重要,这也就牵扯到了为什么 javascript 是单线程的原因所在。

作者:evan 链接:https://www.zhihu.com/question/316514618/answer/1311354630 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

写了代码很容易理解

console.log("in");
Promise.resolve()
  .then(() => {
    console.log("promise out1");
    setTimeout(() => {
      console.log("settimeout in");
    });
    Promise.resolve()
      .then(() => {
        console.log("promise in1");
      })
      .then(() => {
        console.log("promise in2");
      });
  })
  .then(() => {
    console.log("promise out2");
  });
setTimeout(() => {
  console.log("settimeout out");
});
console.log("out");
// 执行结果:
// in
// out
// promise out1
// promise in1
// promise out2
// promise in2
// settimeout out
// settimeout in

首先很重要的一个概念是那俩叫做 task 和 job...

我觉得其实就是为了处理回调地狱的 然后 error 在 job 中都是在链中的 不需要在去 try,能够保存值在后面 then 出来 等等优势

调用时机的优势在我们的开发中 ....基本无意义 你真会去单纯使用 job 去处理吗... 不还是要么和 io 关联要么和 task 关联去使用 所以我暂时还没有理解 job 的设计为啥需要和 task 又这么大的差异

为了减少锁的使用和锁的范围,Chromium 采用了一个比较巧妙的方法:简单来讲,MessageLoop 维护有两个队列,一个 work_queue,一个 incoming_queue。消息循环不断从 work_queue 取任务并执行,新加入任务放入 incoming_queue。当 work_queue 中的任务都执行完后,再把 incoming_queue 拷贝到 work_queue(需要加锁)。这样避免了每执行一个任务都要去加锁。

原文链接:https://blog.csdn.net/wy5761/article/details/44095089

Last Updated: 11/27/2021, 6:11:48 PM