promise與setTimeout的執行順序問題
阿新 • • 發佈:2018-12-17
有一次在面試題中有做到promise與setTimeout的執行順序,當時有點懵,執行順序還是弄錯了一點點,這裡記錄下
1.輸出
setTimeout(function() { console.log(111) }, 0); setTimeout(function() { console.log(333) }, 1000); new Promise(function(resolve){ console.log(444); resolve(); console.log(555); }).then(function(){ console.log(666); }); console.log(777); async function test1() { console.log("test1"); await test2(); console.log("test1 last"); } async function test2() { console.log("test2"); } test1();
- 輸出結果
2.個人理解
- 首先執行同步程式碼,然後以事件輪詢的方式執行非同步程式碼
- promise中的非同步體現在.then()和.catch()中
- 而promise中的function裡的是同步程式碼
- 上面的程式碼是先執行promise裡的同步程式碼,然後執行腳本里本身的同步程式碼
- async無論方法是同步還是非同步都可以用async關鍵字來進行標識
- 因為用async標識只是顯示錶明在該方法內,可能會用到await關鍵字使其變為非同步方法,而且將該非同步方法進行了明確的劃分,只有用了await關鍵字時才是非同步操作,其餘一併為同步操作
- 同 Generator 函式一樣,async 函式返回一個 Promise 物件,可以使用 then 方法添加回調函式
- 當函式執行的時候,一旦遇到 await 就會先返回,等到觸發的非同步操作完成,再接著執行函式體內後面的語句
- await 命令後面的 Promise 物件,執行結果可能是 rejected,所以最好把 await 命令放在 try...catch 程式碼塊中
3.其他
- 在網上還找到了一些資料
參考了這篇文章的一些內容 參考文章
setImmediate(function(){ console.log(1); },0); setTimeout(function(){ console.log(2); },0); new Promise(function(resolve){ console.log(3); resolve(); console.log(4); }).then(function(){ console.log(5); }); console.log(6); process.nextTick(function(){ console.log(7); }); console.log(8);
- 輸出結果: 3 4 6 8 7 5 2 1
macro-task: script (整體程式碼),setTimeout, setInterval, setImmediate, I/O, UI rendering.
micro-task: process.nextTick, Promise(原生),Object.observe,MutationObserver
- 第一步. script整體程式碼被執行,執行過程為
建立setImmediate macro-task
建立setTimeout macro-task
建立micro-task Promise.then 的回撥,並執行script console.log(3); resolve(); console.log(4); 此時輸出3和4,雖然resolve呼叫了,執行了但是整體程式碼還沒執行完,無法進入Promise.then 流程。
console.log(6)輸出6
process.nextTick 建立micro-task
console.log(8) 輸出8
- 第一個過程過後,已經輸出了3 4 6 8
- 第二步. 由於其他micro-task 的 優先順序高於macro-task。
- 此時micro-task 中有兩個任務按照優先順序process.nextTick 高於 Promise,所以先輸出7,再輸出5
- 第三步,micro-task 任務列表已經執行完畢,家下來執行macro-task. 由於setTimeout的優先順序高於setIImmediate,所以先輸出2,再輸出1。
優先順序: promise.Trick()>promise的回撥>setTimeout>setImmediate