微任務,宏任務順序

前言

JS中整個循環當中,僅存在一個《》html

理解一下概念問題 微任務,宏任務node

 

宏任務須要屢次事件循環才能執行完,微任務是一次性執行完的;promise

 

2.宏任務macrotask:瀏覽器

(事件隊列中的每個事件都是一個macrotask)異步

優先級:主代碼塊 > setImmediate > MessageChannel > setTimeout / setInterval函數

好比:setImmediate指定的回調函數,老是排在setTimeout前面測試

 

3.微任務包括:ui

優先級:process.nextTick > Promise > MutationObserverspa

 

須要多注意  process.nextTick 永遠大於 promise.then,code

緣由其實很簡單

 

在Node中,_tickCallback在每一次執行完TaskQueue中的一個任務後被調用,而這個_tickCallback中實質上幹了兩件事:

1.nextTickQueue中全部任務執行掉(長度最大1e4,Node版本v6.9.1)

2.第一步執行完後執行_runMicrotasks函數,執行microtask中的部分(promise.then註冊的回調)

盜一張圖:

 

可是js異步有一個機制,就是遇到宏任務,先執行宏任務,將宏任務放入eventqueue,而後在執行微任務,將微任務放入eventqueue,

這兩個queue不是一個queue。當你往外拿的時候先從微任務裏拿這個回掉函數,而後再從宏任務的queue上拿宏任務的回掉函數。 

 

 

 

 

 

 

這張圖能夠看出:

  1. 存在微任務的話,那麼就執行全部的微任務
  2. 微任務都執行完以後,執行第一個宏任務,
  3. 循環 1, 2

 這樣 能夠總結一下如何分析異步執行的順序:
首先咱們分析有多少個宏任務;
在每一個宏任務中,分析有多少個微任務;
根據調用次序,肯定宏任務中的微任務執行次序;
根據宏任務的觸發規則和調用次序,肯定宏任務的執行次序;

 

下面作個測試:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        console.log('1');//
        setTimeout(function () {
            console.log('2');//
            new Promise(function (resolve) {
                console.log('3');//
                resolve();
            }).then(function () {
                console.log('4');//
            })
        }, 0);
        new Promise(function (resolve) {
            console.log('5');//
            resolve();
        }).then(function () {
            console.log('6');//
        });
        setTimeout(function () {
            console.log('7');//
            new Promise(function (resolve) {
                console.log('8');//
                resolve();
            }).then(function () {
                console.log('9');//
            });
        })
    </script>
</body>

</html>

測試結果爲:   1->5->6->2->3->4->7->8->9

若是上面實在node 環境中

測試結果爲:   1->5->6->2->3-->7->8->4->9

 

分析

  setTimeout內部回調函數執行順序在瀏覽器環境與node環境是有差別的。
      1.瀏覽器環境是執行完seTimeout內部回調函數內容 \color{red}{(僅僅限於當前例子,若是setTimeout內部還有setTimeout等異步代碼,那就另當別論)}
第一個setTimeout中的「2 3 4」先與第二個setTimeout中的「7 8 9」打印。      2.node環境中setTimeout內部若是還有異步操做,直接跳到下一個setTimeout回調代碼中。至於兩個setTimeout中promose.then內部的執行順去取決於微任務的入隊順序
相關文章
相關標籤/搜索