Twitter上的一个问题,起先是在知乎一篇专栏上看到的。问下列代码的执行顺序
这里没有定义doSomething
和doSomethingElse
, 所以puzzle #3
的解释可能不一样。
先给出下面的定义:
function doSomething() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('something');
}, 1000);
});
}
function doSomethingElse() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('somethingElse');
}, 1500);
});
}
Puzzle #1
console.time('case 1')
doSomething().then(() => {
return doSomethingElse()
}).then(function finalHandler(res) {
console.log(res)
console.timeEnd('case 1')
})
- 打印信息为
somethingElse case 1: 2511.396ms
- 执行顺序为
doSomething() |----------| doSomethingElse() |---------------| finalHandler(somethingElse) |->
- 这是正常写promise的代码
Puzzle #2
console.time('case 2')
doSomething().then(() => {
doSomethingElse()
}).then(function finalHandler(res) {
console.log(res)
console.timeEnd('case 2')
})
- 打印信息
undefined case 2: 1016.124ms
- 执行顺序
doSomething() |----------| doSomethingElse() |---------------| finalHandler(undefined) |->
- 这里相比Puzzle #1 在
then
中去掉了return
,所以doSomethingElse
是异步执行的。而没有return
任何值,所以finalHandler
中为undefined
Puzzle #3
console.time('case 3')
doSomething().then(
doSomethingElse()
).then(function finalHandler(res) {
console.log(res)
console.timeEnd('case 3')
})
- 打印信息
something case 3: 1021.446ms
- 执行顺序
doSomething() |----------| doSomethingElse() |---------------| finalHandler(something) |->
- 这里发生了值穿透??,看了这个后还是有点不太明白。
doSomethingElse
这里不会等待doSomething
执行完毕后执行么 then
需要接受一个函数,这里却传了一个值
这里如果doSomethingElse
返回的是一个函数,结果就不一样了
function doSomethingElse() {
return () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('somethingElse');
}, 1500);
});
}
}
- 打印信息:
somethingElse case 3: 2522.012ms
- 执行顺序
doSomething() |----------| doSomethingElse() |----------------| finalHandler(something) |->
Puzzle #4
console.time('case 4')
doSomething().then(doSomethingElse)
.then(function finalHandler(res) {
console.log(res)
console.timeEnd('case 4')
})
- 打印结果:
somethingElse case 4: 2537.144ms
- 执行顺序
doSomething() |----------| doSomethingElse(something) |---------------| finalHandler(somethingElse) |->
- 这里给
then
传递都还是一个函数,所以和Puzzle #1的结果是一样的