Page 189 - AngularJS权威教程
P. 189
17.2 为什么使用 promise 169
User.get(fromId) 1
.then(function(user) {
return user.friends.find(toId);
}, function(err) {
// 没找到用户 2
})
.then(function(friend) {
return user.sendMessage(friend, message); 3
}, function(err) {
// 用户的朋友返回了异常
})
.then(function(success) { 4
// user was sent the message
}, function(err) {
// 发生错误了 5
});
代码不仅仅是可读性变高了,也更容易理解了。我们可以保证回调是一个值,而不用处理回
调接口。 6
注意,在第一个例子中,我们需要用跟处理正常状况不同的方式去处理异常。需要确定什么
7
时候使用回调来处理错误,在一个传统的API响应函数签名(惯例的方法签名通常是(err, data))
中检查错误是否已定义。我们所有的API方法都需要实现同样的结构。
8
在第二个例子里,我们用同样的方式处理成功和错误。合成对象将会以常见的方式接收到错
误。promise API就是用于明确地执行或者拒绝promise的,所以不必担心我们的方法实现了不同
的方法签名。 9
17.2 为什么使用 promise 10
使用promise的附带收获之一是逃脱了回调地狱。promise让异步函数看上去像同步的。基于 11
同步函数,我们可以按照预期来捕获返回值和异常值。
可以在程序中的任何时刻捕捉错误,并且绕过依赖于程序异常的后续代码。我们不需要思考 12
这个同步代码带来的好处,就已经达到上述目的了 —— 它就在代码的本质中。
因此,使用promise的目的是:获得功能组合和错误冒泡(error bubbling)能力的同时,保持 13
代码异步运行的能力。
promise是头等对象,自带了一些约定。 14
只有一个resolve或者reject会被调用到:
resolve被调用时,带有一个履行值; 15
reject被调用时要带一个拒绝原因。
如果promise被执行或者拒绝了,依赖于它们的处理程序仍然会被调用; 16
处理程序总是会被异步调用。
此外,可以把promise串起来,并且允许代码以通常运行的方式来处理。从一个promise冒出 17
的异常会贯穿整个promise链。
18
promise总是异步执行的,可以放心使用,无需担心它们会阻塞应用的其他部分。