twitter 上有一道关于 Promise 的题,执行顺序是怎样?见下图:

我们假设 doSomething 耗时 1s,doSomethingElse 耗时 1.5s:

functiondoSomething(){returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve('something')},1000)})}functiondoSomethingElse(){returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve('somethingElse')},1500)})}

1. 第一种情况:

console.time('case1')doSomething().then(()=>{returndoSomethingElse()}).then(functionfinalHandler(res){console.log(res)console.timeEnd('case1')})

打印出:

somethingElsecase1:2509ms

执行顺序为:

doSomething()|----------|doSomethingElse()|---------------|finalHandler(somethingElse)|->

解释:正常的 Promise 用法。


2. 第二种情况:

console.time('case2')doSomething().then(function(){doSomethingElse()}).then(functionfinalHandler(res){console.log(res)console.timeEnd('case2')})

打印出:

undefinedcase2:1009ms

执行顺序为:

doSomething()|----------|doSomethingElse()|---------------|finalHandler(undefined)|->

解释:因为没有使用 return,doSomethingElse 在 doSomething 执行完后异步执行的。

3. 第三种情况:

console.time('case3')doSomething().then(doSomethingElse()).then(functionfinalHandler(res){console.log(res)console.timeEnd('case3')})

打印出:

somethingcase3:1008ms

执行顺序为:

doSomething()|----------|doSomethingElse()|---------------|finalHandler(something)|->

解释:上面代码相当于:

console.time('case3')vardoSomethingPromise=doSomething()vardoSomethingElsePromise=doSomethingElse()doSomethingPromise.then(doSomethingElsePromise).then(functionfinalHandler(res){console.log(res)console.timeEnd('case3')})

而我们知道 then 需要接受一个函数,否则会值穿透,所以打印 something。

4. 第四种情况:

console.time('case4')doSomething().then(doSomethingElse).then(functionfinalHandler(res){console.log(res)console.timeEnd('case4')})

打印出:

somethingElsecase4:2513ms

执行顺序为:

doSomething()|----------|doSomethingElse(something)|---------------|finalHandler(somethingElse)|->

解释:doSomethingElse 作为 then 参数传入不会发生值穿透,并返回一个 promise,所以会顺序执行。