事件循环范围内microtask和宏任务之间的区别事件循环范围内microtask和宏任务之间的区别

2019-05-09 10:22发布

我刚刚读完的承诺/ A +规格和偶然的条款microtask和宏任务:看http://promisesaplus.com/#notes

我从来没有听说过这些术语之前,现在我很好奇的差异可能是什么?

我已经试图找到在网络上的一些信息,但所有我发现是从w3.org档案这个帖子(不解释对我来说差别): http://lists.w3.org/Archives /Public/public-nextweb/2013Jul/0018.html

另外,我发现所谓的“宏任务”的NPM模块: https://www.npmjs.org/package/macrotask再次,它没有明确什么区别到底是。

我所知道的是,它有事情做与事件循环,如在https://html.spec.whatwg.org/multipage/webappapis.html#task-queue和HTTPS://html.spec.whatwg .ORG /多页/ webappapis.html#执行-A-microtask检查点

我知道我应该在理论上能够提取的区别自己,因为这WHATWG规范。 但我敢肯定,其他人可以从由专家给出一个简短的解释中受益。

Answer 1:

事件循环的一个复飞必须从宏任务队列进行处理恰好有一个任务(这个队列简称在任务队列 WHATWG规范 )。 这个宏任务完成后,所有可用的microtasks将被处理,即在相同的复飞循环。 虽然这些microtasks进行处理,他们可以排队更microtasks,这都将运行一个接一个,直到microtask队列被耗尽。

这有什么实际后果?

如果microtask递归排队等microtasks,直到下一个宏任务处理可能需要很长的时间。 这意味着,你可以用堵塞UI结束,或完成一些I / O应用程序中的空转。

然而,至少有关的Node.js的process.nextTick功能(哪些队列microtasks),存在通过process.maxTickDepth的手段对这种阻挡一个内置的保护。 这个值被设置为1000默认情况下,削减microtasks的进一步处理达到此限制后,允许要处理的下一个宏任务

因此,当使用什么?

基本上,使用microtasks当你需要在同步异步方式做的东西(即当你会说在最近的将来执行这个(微)任务 )。 否则,坚持宏任务

例子

宏任务:的setTimeout,setInterval的,setImmediate,requestAnimationFrame,I / O,UI渲染
microtasks:process.nextTick,承诺,Object.observe,MutationObserver



Answer 2:

我写这个帖子,其中包括互动的例子https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/

更新:我也给了谈这个https://www.youtube.com/watch?v=cCOL7MC4Pl0 。 会谈进入更多细节,包括任务和microtasks如何与渲染互动。



Answer 3:

在基本概念规格 :

  • 事件循环具有一个或多个任务的队列。(任务队列是宏任务队列)
  • 每个事件循环有microtask队列。
  • 任务队列=宏任务队列!= microtask队列
  • 任务可被推入宏任务队列,或microtask队列
  • 当任务被推入队列(微/宏),我们的意思是准备工作完成后,做任务,现在可以执行。

而事件循环过程模型如下:

当调用堆栈是空的,执行步骤-

  1. 选择任务队列的最古老的任务(任务A)
  2. 如果任务A为空(意味着任务队列为空),则跳转至步骤6
  3. 设置“当前正在运行的任务”到“任务A”
  4. 运行“任务A”(指运行回调函数)
  5. 设置为“正在运行任务”为空,删除“任务A”
  6. 执行microtask队列
    • (a)以microtask队列。选择最旧的任务(任务x)的
    • (b)中。如果任务x是空(意味着microtask队列为空),则跳转到步骤(G)
    • (三).SET“当前正在运行的任务”到“任务X”
    • (d).RUN “任务X”
    • (五).SET“当前正在运行的任务”为空,删除“任务X”
    • (F)。选择在microtask队列下一最早的任务,则跳转到步骤(b)中
    • (克).finish microtask队列;
  7. 跳转到步骤1。

一个简化的过程模型是如下:

  1. 运行宏任务队列中最早的任务,然后将其删除。
  2. 运行microtask队列中所有可用的任务,然后将其删除。
  3. 下一轮:在宏任务队列中运行的下一个任务(跳转步骤2)

事情要记住:

  1. (在宏任务队列)任务运行时,新的事件可能是registered.So新的任务可能是created.Below两个新创建的任务:
    • promiseA.then()的回调是一个任务
      • promiseA解决/拒绝:任务将在本轮事件循环推入microtask队列。
      • promiseA未决:任务将在未来轮事件循环的推入microtask队列(可以是下一轮)
    • 的setTimeout(回调,N)的回调是一个任务,并且将被推入宏任务队列,即使n为0;
  2. 在microtask队列任务将在本轮运行,而在宏任务队列的任务必须等待下一轮事件循环。
  3. 大家都知道的“点击”,“滚动”,“阿贾克斯”,“setTimeout的” ......是任务的回调,但是我们也应该记住的js代码作为一个整体在脚本标签是一个任务(宏任务)了。


文章来源: Difference between microtask and macrotask within an event loop context