宏觀和微觀任務
JavaScript 引擎等待宿主環境配置設定宏觀任務,在作業系統中,通常等待的行為都是一個事件循環,是以在 Node 術語中,也會把這個部分稱為事件循環。
這裡每次的執行過程,其實都是一個宏觀任務。我們可以大概了解:宏觀任務的隊列就相當于事件循環。
在宏觀任務中,JavaScript 的 Promise 還會産生異步代碼,JavaScript 必須保證這些異步代碼在一個宏觀任務中完成,是以,每個宏觀任務中又包含了一個微觀任務隊列:
Promise
Promise 是 JavaScript 語言提供的一種标準化的異步管理方式,它的總體思想是,需要進行 io、等待或者其它異步操作的函數,不傳回真實結果,而傳回一個“承諾”,函數的調用方可以在合适的時機,選擇等待這個承諾兌現(通過 Promise 的 then 方法的回調)。
promise基本用法如下:
function sleep (duration) {
return new Promise(function(resolve,reject){
setTimeout(resolve,duration);
})
}
sleep(1000).then(() => console.log('ok'))
這段代碼定義了一個函數sleep 它的作用是等候傳入參數指定時長。
promise的then回調是一個異步的執行過程。
var r = new Promise(function(resolve,reject){
console.log('a')
resolve()
})
r.then(() => console.log("c"))
console.log("b")
列印出來的結果是abc/ 在進入c之前,對象r已經得到了resolve,但是promise為異步操作,是以c無法出現在b之前。
與setTimeout 一起執行promise
var r= new Promise(function (resolve,reject){
console.log("a")
resolve()
})
setTimeout(() => console.log("d"),0)
r.then(() => console.log("c"))
console.log("b")
得到的結果為abcd。為什麼d在後面呢?
因為promise是JavaScript引擎内部的微任務,而setTimeout是遊覽器的api,它産生宏任務。
function sleep(duration){
return new Promise(function(resolve,reject){
console.log("b")
setTimeout(resolve,duration)
})
}
console.log("a")
sleep(5000).then(() => console.log("c"))
此段代碼執行結果為abc
async / await
function sleep (duration){
return new Promise(function(resolve,reject){
setTimeout(resolve,duration);
})
}
async function foo() {
console.log("a")
await sleep(2000)
console.log("b")
}
function sleep(duration){
return new Promise(function(resolve,reject){
setTimeout(resolve,duration)
})
}
async function foo(name){
await sleep(2000);
console.log(name)
}
async function foo2() {
await foo("a")
await foo("b")
}