1. 程式人生 > >任務隊列等相關

任務隊列等相關

當前 sta str 打印 依次 不清楚 試題 朋友 結果

上周五,一個朋友發給我一道面試題,代碼如下:

console.log(1);
setTimeout(console.log(2), 0);
Promise.resolve().then(res => {
    console.log(3);
}).then(res=>{
    console.log(4);
})
console.log(5);

朋友說在控制臺跑完的結果是依次打印出 1 2 5 3 4,但是不清楚為什麽,希望我幫他分析下。


額,我覺得打印結果應該是 1 5 2 3 4,女人的直覺告訴我,setTimeOut裏的那個打印,是在下次事件循環時才會執行的。。

然而,結果並非如此。說明我還處於朦朧狀態啊,於是乎,開始去網上找博客。

以下內容均是在博客中看到的內容,加上一點點自己的理解,至於是否客觀正確,這個另說哈,時間會檢驗一切的。


JS主要用來操作DOM,如果是多線程,會比較混亂,所以是單線程的。

同步:主線程上執行的任務。

異步:進入任務隊列 的任務,只有等主線程上的任務執行完了,任務隊列中的任務才會進入主線程執行。


瀏覽器中的事件循環--Event Loop(我盜的圖 哈哈)

技術分享圖片

從上圖看到(下面這段也是抄的??):

  1. 主線程運行的時候產生堆(heap)和棧(stack)
  2. 棧中的代碼調用各種外部API,它們在"任務隊列"中加入各種事件(click,load,done)
  3. 只要棧中的代碼執行完畢,主線程就會去讀取"任務隊列",將隊列中的事件放到執行棧中依次執行。
  4. 主線程繼續執行,當再調用外部API時又加入到任務隊列中,等主線程執行完畢又會接著將任務隊列中的事件放到主線程中。
  5. 上面整個過程是循環不斷的。

不知道從哪引用的

除了setTimeout和setInterval這兩個方法,Node.js還提供了另外兩個與"任務隊列"有關的方法:process.nextTick和setImmediate。

process.nextTick方法可以在當前"執行棧"的尾部----下一次Event Loop(主線程讀取"任務隊列")之前----觸發回調函數。也就是說,它指定的任務總是發生在所有異步任務之前。 
setImmediate方法則是在當前"任務隊列"的尾部添加事件,也就是說,它指定的任務總是在下一次Event Loop時執行,這與setTimeout(fn, 0)很像。

結論

其實還有很多東西沒有好好整理出來,下面只是大概記錄下,詳細的內容,查看下面的博文鏈接哈

如果在原來的setTimeout console外面包了function。執行結果是1 5 3 4 2。

首先,1 5 是同步任務,所以會被依次添加到任務隊列中,然後setTimeout屬於宏任務,會在0毫秒後添加到任務隊列中,Promise是異步的,屬於微任務,在同步任務執行完畢後執行,並且它也是鏈式的,所以它的回調函數會依次被添加到微任務中,微任務會在任務隊列中的每一個task執行完後執行


But,還有個問題沒搞明白:
setTimeout( function(){ console.log(2) }, 0 );

setTimeout( console.log(2), 0 );
有啥子區別呢?執行結果不一樣呢

參考:

你真的了解Event Loop(事件環)嗎?

任務隊列等相關