前段-一个小测试

一个小测试

如题,以下四种promise流程有什么不同?

1
2
3
4
5
6
7
8
9
10
11
doSomething().then(function () {
return doSomethingElse();
});

doSomething().then(function () {
doSomethingElse();
});

doSomething().then(doSomethingElse());

doSomething().then(doSomethingElse);

建议看到的同学可以自己回答下看看,如果已经能够很清楚的弄清这四种情况了,那么说明你对promise已经很熟练了,接下来的就可以打打酱油随便看看了。

promise给我们一个then()或catch()方法来解决回调黑洞,我们在then中可以做三件事:

  1. return 另一个 promise
  2. return 一个具体的值或undefined
  3. 抛出一个同步错误

一旦你弄清楚了这些,你就理解了promise,接下来我们逐条看一下。

return 另一个 promise

这种是promise里最常见的用法,注意,我们在then中return了第二个promise-这个return至关重要。如果没有return,那我们将仅仅执行了getUserAccountById()而没有返回任何东西,那么接下来的函数中不会得到userAccount,而是会得到undefined,我们可以称这种情况为non-returning。

1
2
3
4
5
getUserByName('user1').then(function (user) {
return getUserAccountById(user.id);
}).then(function (userAccount) {
// 得到userAccount
});
return 一个具体的值或undefined

return undefined通常是一个错误,但是return一个值却是连接同步代码和promise代码的一个不错的方法。例如当我们对用户信息存在缓存时:

1
2
3
4
5
6
7
8
9
10
getUserByName('user1').then(function (user) {
if (inMemoryCache[user.id]) {
return inMemoryCache[user.id];
// returning 了一个同步的值
}
return getUserAccountById(user.id);
// returning 了一个promise
}).then(function (userAccount) {
// 可以得到userAccount
});

第二个then不会关心前一个then返回的是同步还是异步的结果,而第一个then中的函数可以根据实际场景自由选择返回哪一种。

抛出一个同步错误

throw 是promise的另一个神奇之处,catch可以接收到一个同步的错误,也可接受来自被拒绝的promise的异步错误。例如,JSON.parse(params)中params无效时报的错误将会被catch捕捉。

介绍完了以上三种情况,那么接下来我们来看这一种情况:

1
2
3
4

Promise.resolve('foo').then(Promise.resolve('bar')).then(function (result) {
console.log(result);
});

以上的例子将会输出什么结果?

可能你觉得是bar,答案其实是foo。原因是我们在第一个then中传的是一个非函数-(例如promise)时,实际上会被编译为then(null),所以以上的例子等同于

1
2
3
Promise.resolve('foo').then(null).then(function (result) {
console.log(result);
});

总结一下,当then中传的是non-returning时(上面提到的),那么下一个then中的参数是undefined;

当then中传的是non-function时,下一个then中的参数得到的是then(null)之前的参数。

所以,开篇提到的问题中:

2为non-returning场景,处理过程为:

doSomething
|—————–|
doSomethingElse(undefined)
|——————|
finalHandler(undefined)
|——————|

3为non-function场景,处理过程为:

doSomething
|—————–|
doSomethingElse(undefined)
|———————————|
finalHandler(resultOfDoSomething)
|——————|

4是正常流程:

doSomething
|—————–|
doSomethingElse(resultOfDoSomething)
|——————|
finalHandler(resultOfDoSomethingElse)
|——————|

1和4的区别为在doSomethingElse中拿到的是undefined:

doSomething
|—————–|
doSomethingElse(undefined)
|——————|
finalHandler(resultOfDoSomethingElse)
|——————|

一个关于promise基础的小测试,感谢阅读~