高级前端
js
【Q668】JS 中异步任务为何分为微任务与宏任务

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

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

Author 回答者: shfshanyue (opens in a new tab)

TODO

Author 回答者: CheckLee (opens in a new tab)

转一下知乎的回答。 为了插队。 一个 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 (opens in a new tab) 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

写了代码很容易理解

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

Author 回答者: heretic-G (opens in a new tab)

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

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

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

Author 回答者: illumi520 (opens in a new tab)

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

原文链接:https://blog.csdn.net/wy5761/article/details/44095089 (opens in a new tab)