最近看了一些異步的文章,有一些做者沒有寫代碼也把錯誤的理解放上來。想一想,我也應該總結一些,以前面試也有過一道題目,雖說是考察異步,但其實就是考察異步當中的任務隊列。給你一道題目,你以爲會依次輸出什麼?git
console.log('1') Promise.resolve().then(() => console.log('2')) setTimeout(() => {console.log('3'); Promise.resolve().then(() => console.log('4'))}, 0) Promise.resolve().then(() => console.log('5')) setTimeout(() => console.log('6'), 0) console.log('7')
答案是github
1 7 2 5 3 4 6
若是你知道爲何會輸出這些的話,那我想你沒必要看下面了,由於你也有大概的理解,若是沒有的話,我就跟你分析一下吧。面試
先看一張圖吧,是拿別人的,有部分緣由也是由於他寫的文章有錯誤,我才總結。segmentfault
先理解這張圖片吧,我簡單介紹一下。markdown
而後,js運行就是運行主線程->運行任務隊列異步
固然,這只是大概的介紹,真正的堆和棧並非和他說的同樣,棧裏面還有內存棧和調用棧,內存棧又有全局的內存棧,也有某個函數的內存棧,固然,函數內部的內存棧又放在了堆裏面。這裏面的棧,僅僅是表明了調用棧。函數
什麼是宏任務隊列?
宏任務隊列macrotasks: setTimeout, setInterval, setImmediate, I/O, UI renderingoop
上面的基本操做就是宏任務隊列spa
微任務隊列microtasks: process.nextTick, Promise, MutationObserver線程
上面的基本操做就是微任務隊列
我就簡單的說一下js裏面執行順序吧:
是否是很簡單?
那麼上面那道題的結果無非就是
// 一開始,主線程 console.log('1'); console.log('7'); // 下一步,主線程 Promise.resolve().then(() => console.log('2')) // 下一步,主線程 Promise.resolve().then(() => console.log('5')) // 下一步,主線程 setTimeout(() => {console.log('3')}, 0) // 下一步,主線程 Promise.resolve().then(() => console.log('4')) // 下一步,主線程 setTimeout(() => console.log('6'), 0)
看了一下不少文章,覺得很難,很想畫圖,可是在寫的過程當中,發現其實真的很簡單,只要好好了解js裏面的引擎就行了,js仍是一個很強大的單線程語言。