JavaScript 中 的异步任务

在 JS 中, 基本上来说 有 三种 异步操作

  • [MicroTask] MicroTask 是 当前 执行 的 Task 结束后立即执行的 工作(work). MicroTask 不可取消以保证只执行一次并且在 当前 Task 结束后立即执行。

  • [MacroTask] MacroTask 用于 稍后要执行的工作, 比如 setTimeout.
    MacroTask 通常是可以取消的, 在一定的延迟过后至少会执行一次。
    怎么理解这句话呢?
    setTimeout 来说,

var timer = setTimeout(function fn(){
  console.log('timeout after 5000 delay');
}, 5000);

如果 5000ms 之内, 我们可以 执行

clearTimeout(timer);

这样函数 fn 就不会再执行, MacroTask fn 也就取消了。但是如果没有取消操作的话, 就会执行函数 fn, 这里 函数 fn 会执行一次。

  • [EventTask] 用来 监听 未来的 事件。在某个未知的延迟之后 会 执行 0次或者多次

摘录:

 * A JS VM can be modeled as a [MicroTask] queue, [MacroTask] queue, and [EventTask] set.
 *
 * - [MicroTask] queue represents a set of tasks which are executing right after the current stack
 *   frame becomes clean and before a VM yield. All [MicroTask]s execute in order of insertion
 *   before VM yield and the next [MacroTask] is executed.
 * - [MacroTask] queue represents a set of tasks which are executed one at a time after each VM
 *   yield. The queue is ordered by time, and insertions can happen in any location.
 * - [EventTask] is a set of tasks which can at any time be inserted to the end of the [MacroTask]
 *   queue. This happens when the event fires.

从中可得知:

  • MicroTask 的执行时机或者执行条件:
    1、 执行栈为空, 也就是 Execution Context Stack 里不再有栈帧。
    且 在 VM yield 之前
    2、下一个 MacroTask 执行之前
    MicroTask 执行顺序: 按照 插入队列的顺序执行。

  • MacroTask 执行时机:
    每次 VM yield 之后,每次执行一个 MacroTask
    MacroTask 队列是按照时间排序的, 并且 MacroTask的插入可以在任何位置

  • EventTask 发生时机: 触发事件
    EventTask 可以在任何时间插入到 MacroTask 队列尾。

references:
https://github.com/angular/zone.js/blob/master/dist/zone.js.d.ts

    原文作者:萧哈哈
    原文地址: https://www.jianshu.com/p/6c4db8fb2ed3
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞