有一次在面試題中有做到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);
macro-task: script (整體代碼),setTimeout, setInterval, setImmediate, I/O, UI rendering.
micro-task: process.nextTick, Promise(原生),Object.observe,MutationObserver
創建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
正在努力學習中,若對你的學習有幫助,留下你的印記唄(點個贊咯^_^)