事件佇列
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即事件佇列。
實現非同步
- 回撥函式
- 事件監聽
- 釋出/訂閱
- Promise 物件
- generrator