通过microtasks和macrotasks看JavaScript异步任务执行顺序
在前端开发中,经常需要处理一些异步任务,比如从后台请求数据、异步加载图片等等。JavaScript提供了多种方式来实现异步操作,其中使用setTimeout
、setInterval
、Promise
等方法是比较常见的做法。但是这些异步任务的执行顺序并不总是按照我们预期的那样,这时候就需要了解 JavaScript 中的 microtasks 和 macrotasks 的概念。
什么是 microtasks 和 macrotasks?
在 JavaScript 引擎中,有两个任务队列:microtasks 和 macrotasks。它们分别存储着不同类型的任务。
- macrotasks(宏任务):包括整体代码
script
、setTimeout
、setInterval
、I/O
操作、UI 渲染等。 - microtasks(微任务):包括
Promise.then
、process.nextTick
、MutationObserver
等。
执行顺序上,每个事件循环中,macrotask 队列只会执行一个任务,而 microtask 队列可以执行多个任务,直到队列为空为止。
为什么要了解 microtasks 和 macrotasks?
很多情况下,我们希望程序在执行完某些异步任务后才继续执行后面的逻辑,或者需要根据异步任务的执行结果来决定下一步的操作。了解 microtasks 和 macrotasks 的执行顺序可以帮助我们更好地控制程序的执行流程,从而避免一些意外的行为。
示例代码
接下来,我们通过一些示例代码来演示 microtasks 和 macrotasks 的执行顺序。
--------------------- --------------------- - --------------------------- -- --- --------------------------------- - ------------------------ ------------------ - ------------------------ --- --------------------- - --------------------------- -- --- -------------------
上面的代码中包含两个 setTimeout
和两个 Promise.then
。按照代码的书写顺序,应该先输出 start
,然后执行第一个 setTimeout
,接着执行第一个 Promise.then
,再执行第二个 Promise.then
,最后执行第二个 setTimeout
,输出 end
。但是实际执行结果却是:
----- --- -------- -------- ----------- -----------
为什么会出现这样的结果呢?这是因为 Promise.then
是 microtask,而 setTimeout
是 macrotask。所以在执行完 console.log('end')
后,JavaScript 引擎会先处理当前的 microtask 队列,即执行两个 Promise.then
,然后才会处理 macrotask 队列。因此先输出了 promise1
和 promise2
。
如何利用 microtasks 和 macrotasks 控制程序流程?
通过上面的示例代码,我们可以发现,在异步任务中使用 microtasks 来控制程序的执行顺序是比较方便的。例如,我们可以利用 Promise
来实现异步操作的串行执行:
-------- ------------ - ------ --- ------------------------- ------- - --------------------- - -------------------------- ---------- -- ------ --- - -------- ------------ - ------ --- ------------------------- ------- - --------------------- - -------------------------- ---------- -- ----- --- - ---------------------------- - ------ ------------- ------------------ - -------------------- ---
在上面的代码中,我们定义了两个异步任务 asyncTask1
和 asyncTask2
,并使用 Promise
实现了这两个任务的串行执行。这里
来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/9425