天天看點

javaScript雜談之Promise

宏觀和微觀任務

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")
}      

繼續閱讀