Event Loop

fefe發表於2019-12-30

事件佇列

Javascript是單執行緒,單執行緒就意味著所有任務需要排隊。然後會將所有任務分成兩類:同步任務和非同步任務!同步任務:在主執行緒上執行的任務,只有前一個任務執行完成,才會執行後一個!非同步任務:不進入主執行緒、而進入“任務佇列”的任務,當主執行緒上的任務執行完,主執行緒才會去執行“任務佇列”。

只有一個main thread主執行緒,主執行緒執行完call-stack執行棧的任務後去檢查非同步的任務佇列,如果非同步事件觸發,則將其加到主執行緒的執行棧。

執行順序

主執行緒 ——> promise.nextick ——> promise.then ——> async ——> setTimeout ——> setInterval ——> setImmediate ——> I/O ——>> UI rendering

巨集任務: 整體程式碼script  setTimeout  setInterval setImmediate(瀏覽器僅IE10支援) I/O操作 UI渲染
微任務: promise.then(非new Promise()) process.nextTick(node中) MutationObserver

promise例項化是主執行緒執行
await 相當於 new Promise()
async 是多個非同步操作的promise物件,相當於then
process.nextTick在當前同步任務最後,非同步任務之前
setImmediate用來操作耗時任務
複製程式碼
async function async1() {
  await async2()
  console.log('async1 end')
}
async function async2() {
  console.log('async2 end')
}
async1()

//transfer
new Promise((resolve, reject) => {
  console.log('async2 end')
  // Promise.resolve() 將程式碼插入微任務佇列尾部
  // resolve 再次插入微任務佇列尾部
  resolve(Promise.resolve())
}).then(() => {
  console.log('async1 end')
})
複製程式碼

圖解執行

當javascript程式碼執行的時候會將不同的變數存於記憶體中的不同位置:堆(heap)和棧(stack)中來加以區分,heap中一般儲存我們的變數,stack一般儲存函式或者方法。stack叫做執行棧,我們的方法依次會在這裡執行。執行棧事件先進後出,任務佇列先進先出。web apis則是代表一些非同步事件,而callback queue即事件佇列。

Event Loop

實現非同步

  1. 回撥函式
  2. 事件監聽
  3. 釋出/訂閱
  4. Promise 物件
  5. generrator

相關文章