twitter 上有一道關於 Promise 的題,執行順序是怎樣?見下圖:
咱們假設 doSomething 耗時 1s,doSomethingElse 耗時 1.5s:promise
function doSomething() { return new Promise((resolve, reject) => { setTimeout(() => { resolve('something') }, 1000) }) } function doSomethingElse() { return new Promise((resolve, reject) => { setTimeout(() => { resolve('somethingElse') }, 1500) }) }
第一種狀況:異步
console.time('case 1') doSomething().then(() => {
return doSomethingElse()函數
}).then(function finalHandler(res) {
console.log(res)
console.timeEnd('case 1')code
})
打印出:it
somethingElse case 1: 2509ms
執行順序爲:io
doSomething() |----------| doSomethingElse() |---------------| finalHandler(somethingElse) |->
解釋:正常的 Promise 用法。console
第二種狀況:function
console.time('case 2') doSomething().then(function () { doSomethingElse() }).then(function finalHandler(res) { console.log(res) console.timeEnd('case 2') })
打印出:im
undefined case 2: 1009ms
執行順序爲:co
doSomething() |----------| doSomethingElse() |---------------| finalHandler(undefined) |->
解釋:由於沒有使用 return,doSomethingElse 在 doSomething 執行完後異步執行的。
第三種狀況:
console.time('case 3') doSomething().then(doSomethingElse()) .then(function finalHandler(res) { console.log(res) console.timeEnd('case 3') })
打印出:
something case 3: 1008ms
執行順序爲:
doSomething() |----------| doSomethingElse() |---------------| finalHandler(something) |->
解釋:上面代碼至關於:
console.time('case 3') var doSomethingPromise = doSomething() var doSomethingElsePromise = doSomethingElse() doSomethingPromise.then(doSomethingElsePromise) .then(function finalHandler(res) { console.log(res) console.timeEnd('case 3') })
而咱們知道 then 須要接受一個函數,不然會值穿透,因此打印 something。
第四種狀況:
console.time('case 4') doSomething().then(doSomethingElse) .then(function finalHandler(res) { console.log(res) console.timeEnd('case 4') })
打印出:
somethingElse case 4: 2513ms
執行順序爲:
doSomething() |----------| doSomethingElse(something) |---------------| finalHandler(somethingElse) |->
解釋:doSomethingElse 做爲 then 參數傳入不會發生值穿透,並返回一個 promise,因此會順序執行。