@@ -8,15 +8,15 @@ Promise 是异步编程的一种解决方案,比传统的解决方案——回
8
8
9
9
` Promise ` 对象有以下两个特点。
10
10
11
- (1)对象的状态不受外界影响。` Promise ` 对象代表一个异步操作,有三种状态:` Pending ` (进行中)、` Fulfilled ` (已成功)和` Rejected ` (已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是` Promise ` 这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
11
+ (1)对象的状态不受外界影响。` Promise ` 对象代表一个异步操作,有三种状态:` pending ` (进行中)、` fulfilled ` (已成功)和` rejected ` (已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是` Promise ` 这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
12
12
13
- (2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。` Promise ` 对象的状态改变,只有两种可能:从` Pending ` 变为` Fulfiled ` 和从` Pending ` 变为` Rejected ` 。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 Resolved (已定型)。如果改变已经发生了,你再对` Promise ` 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
13
+ (2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。` Promise ` 对象的状态改变,只有两种可能:从` pending ` 变为` fulfilled ` 和从` pending ` 变为` rejected ` 。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved (已定型)。如果改变已经发生了,你再对` Promise ` 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
14
14
15
- 注意,为了行文方便,本章后面的` Resolved ` 统一只指` Fulfilled ` 状态,不包含` Rejected ` 状态。
15
+ 注意,为了行文方便,本章后面的` resolved ` 统一只指` fulfilled ` 状态,不包含` rejected ` 状态。
16
16
17
17
有了` Promise ` 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,` Promise ` 对象提供统一的接口,使得控制异步操作更加容易。
18
18
19
- ` Promise ` 也有一些缺点。首先,无法取消` Promise ` ,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,` Promise ` 内部抛出的错误,不会反应到外部。第三,当处于` Pending ` 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
19
+ ` Promise ` 也有一些缺点。首先,无法取消` Promise ` ,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,` Promise ` 内部抛出的错误,不会反应到外部。第三,当处于` pending ` 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
20
20
21
21
如果某些事件不断地反复发生,一般来说,使用 [ Stream] ( https://nodejs.org/api/stream.html ) 模式是比部署` Promise ` 更好的选择。
22
22
@@ -40,9 +40,9 @@ var promise = new Promise(function(resolve, reject) {
40
40
41
41
` Promise ` 构造函数接受一个函数作为参数,该函数的两个参数分别是` resolve ` 和` reject ` 。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
42
42
43
- ` resolve ` 函数的作用是,将` Promise ` 对象的状态从“未完成”变为“成功”(即从 Pending 变为 Resolved ),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;` reject ` 函数的作用是,将` Promise ` 对象的状态从“未完成”变为“失败”(即从 Pending 变为 Rejected ),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
43
+ ` resolve ` 函数的作用是,将` Promise ` 对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved ),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;` reject ` 函数的作用是,将` Promise ` 对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected ),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
44
44
45
- ` Promise ` 实例生成以后,可以用` then ` 方法分别指定` Resolved ` 状态和` Rejected ` 状态的回调函数。
45
+ ` Promise ` 实例生成以后,可以用` then ` 方法分别指定` resolved ` 状态和` rejected ` 状态的回调函数。
46
46
47
47
``` javascript
48
48
promise .then (function (value ) {
@@ -52,7 +52,7 @@ promise.then(function(value) {
52
52
});
53
53
```
54
54
55
- ` then ` 方法可以接受两个回调函数作为参数。第一个回调函数是` Promise ` 对象的状态变为` Resolved ` 时调用,第二个回调函数是` Promise ` 对象的状态变为` Rejected ` 时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受` Promise ` 对象传出的值作为参数。
55
+ ` then ` 方法可以接受两个回调函数作为参数。第一个回调函数是` Promise ` 对象的状态变为` resolved ` 时调用,第二个回调函数是` Promise ` 对象的状态变为` rejected ` 时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受` Promise ` 对象传出的值作为参数。
56
56
57
57
下面是一个` Promise ` 对象的简单例子。
58
58
@@ -68,7 +68,7 @@ timeout(100).then((value) => {
68
68
});
69
69
```
70
70
71
- 上面代码中,` timeout ` 方法返回一个` Promise ` 实例,表示一段时间以后才会发生的结果。过了指定的时间(` ms ` 参数)以后,` Promise ` 实例的状态变为` Resolved ` ,就会触发` then ` 方法绑定的回调函数。
71
+ 上面代码中,` timeout ` 方法返回一个` Promise ` 实例,表示一段时间以后才会发生的结果。过了指定的时间(` ms ` 参数)以后,` Promise ` 实例的状态变为` resolved ` ,就会触发` then ` 方法绑定的回调函数。
72
72
73
73
Promise 新建后就会立即执行。
74
74
@@ -79,17 +79,17 @@ let promise = new Promise(function(resolve, reject) {
79
79
});
80
80
81
81
promise .then (function () {
82
- console .log (' Resolved .' );
82
+ console .log (' resolved .' );
83
83
});
84
84
85
85
console .log (' Hi!' );
86
86
87
87
// Promise
88
88
// Hi!
89
- // Resolved
89
+ // resolved
90
90
```
91
91
92
- 上面代码中,Promise 新建后立即执行,所以首先输出的是` Promise ` 。然后,` then ` 方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以` Resolved ` 最后输出。
92
+ 上面代码中,Promise 新建后立即执行,所以首先输出的是` Promise ` 。然后,` then ` 方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以` resolved ` 最后输出。
93
93
94
94
下面是异步加载图片的例子。
95
95
@@ -164,7 +164,7 @@ var p2 = new Promise(function (resolve, reject) {
164
164
165
165
上面代码中,` p1 ` 和` p2 ` 都是 Promise 的实例,但是` p2 ` 的` resolve ` 方法将` p1 ` 作为参数,即一个异步操作的结果是返回另一个异步操作。
166
166
167
- 注意,这时` p1 ` 的状态就会传递给` p2 ` ,也就是说,` p1 ` 的状态决定了` p2 ` 的状态。如果` p1 ` 的状态是` Pending ` ,那么` p2 ` 的回调函数就会等待` p1 ` 的状态改变;如果` p1 ` 的状态已经是` Resolved ` 或者` Rejected ` ,那么` p2 ` 的回调函数将会立刻执行。
167
+ 注意,这时` p1 ` 的状态就会传递给` p2 ` ,也就是说,` p1 ` 的状态决定了` p2 ` 的状态。如果` p1 ` 的状态是` pending ` ,那么` p2 ` 的回调函数就会等待` p1 ` 的状态改变;如果` p1 ` 的状态已经是` resolved ` 或者` rejected ` ,那么` p2 ` 的回调函数将会立刻执行。
168
168
169
169
``` javascript
170
170
var p1 = new Promise (function (resolve , reject ) {
@@ -210,7 +210,7 @@ new Promise((resolve, reject) => {
210
210
211
211
## Promise.prototype.then()
212
212
213
- Promise 实例具有` then ` 方法,也就是说,` then ` 方法是定义在原型对象` Promise.prototype ` 上的。它的作用是为 Promise 实例添加状态改变时的回调函数。前面说过,` then ` 方法的第一个参数是` Resolved ` 状态的回调函数,第二个参数(可选)是` Rejected ` 状态的回调函数。
213
+ Promise 实例具有` then ` 方法,也就是说,` then ` 方法是定义在原型对象` Promise.prototype ` 上的。它的作用是为 Promise 实例添加状态改变时的回调函数。前面说过,` then ` 方法的第一个参数是` resolved ` 状态的回调函数,第二个参数(可选)是` rejected ` 状态的回调函数。
214
214
215
215
` then ` 方法返回的是一个新的` Promise ` 实例(注意,不是原来那个` Promise ` 实例)。因此可以采用链式写法,即` then ` 方法后面再调用另一个` then ` 方法。
216
216
@@ -230,22 +230,22 @@ getJSON("/posts.json").then(function(json) {
230
230
getJSON (" /post/1.json" ).then (function (post ) {
231
231
return getJSON (post .commentURL );
232
232
}).then (function funcA (comments ) {
233
- console .log (" Resolved : " , comments);
233
+ console .log (" resolved : " , comments);
234
234
}, function funcB (err ){
235
- console .log (" Rejected : " , err);
235
+ console .log (" rejected : " , err);
236
236
});
237
237
```
238
238
239
- 上面代码中,第一个` then ` 方法指定的回调函数,返回的是另一个` Promise ` 对象。这时,第二个` then ` 方法指定的回调函数,就会等待这个新的` Promise ` 对象状态发生变化。如果变为` Resolved ` ,就调用` funcA ` ,如果状态变为` Rejected ` ,就调用` funcB ` 。
239
+ 上面代码中,第一个` then ` 方法指定的回调函数,返回的是另一个` Promise ` 对象。这时,第二个` then ` 方法指定的回调函数,就会等待这个新的` Promise ` 对象状态发生变化。如果变为` resolved ` ,就调用` funcA ` ,如果状态变为` rejected ` ,就调用` funcB ` 。
240
240
241
241
如果采用箭头函数,上面的代码可以写得更简洁。
242
242
243
243
``` javascript
244
244
getJSON (" /post/1.json" ).then (
245
245
post => getJSON (post .commentURL )
246
246
).then (
247
- comments => console .log (" Resolved : " , comments),
248
- err => console .log (" Rejected : " , err)
247
+ comments => console .log (" resolved : " , comments),
248
+ err => console .log (" rejected : " , err)
249
249
);
250
250
```
251
251
@@ -262,7 +262,7 @@ getJSON('/posts.json').then(function(posts) {
262
262
});
263
263
```
264
264
265
- 上面代码中,` getJSON ` 方法返回一个 Promise 对象,如果该对象状态变为` Resolved ` ,则会调用` then ` 方法指定的回调函数;如果异步操作抛出错误,状态就会变为` Rejected ` ,就会调用` catch ` 方法指定的回调函数,处理这个错误。另外,` then ` 方法指定的回调函数,如果运行中抛出错误,也会被` catch ` 方法捕获。
265
+ 上面代码中,` getJSON ` 方法返回一个 Promise 对象,如果该对象状态变为` resolved ` ,则会调用` then ` 方法指定的回调函数;如果异步操作抛出错误,状态就会变为` rejected ` ,就会调用` catch ` 方法指定的回调函数,处理这个错误。另外,` then ` 方法指定的回调函数,如果运行中抛出错误,也会被` catch ` 方法捕获。
266
266
267
267
``` javascript
268
268
p .then ((val ) => console .log (' fulfilled:' , val))
@@ -311,7 +311,7 @@ promise.catch(function(error) {
311
311
312
312
比较上面两种写法,可以发现` reject ` 方法的作用,等同于抛出错误。
313
313
314
- 如果Promise状态已经变成` Resolved ` ,再抛出错误是无效的。
314
+ 如果Promise状态已经变成` resolved ` ,再抛出错误是无效的。
315
315
316
316
``` javascript
317
317
var promise = new Promise (function (resolve , reject ) {
@@ -655,7 +655,7 @@ p1.then(function(value) {
655
655
656
656
** (3)参数不是具有` then ` 方法的对象,或根本就不是对象**
657
657
658
- 如果参数是一个原始值,或者是一个不具有` then ` 方法的对象,则` Promise.resolve ` 方法返回一个新的Promise对象,状态为` Resolved ` 。
658
+ 如果参数是一个原始值,或者是一个不具有` then ` 方法的对象,则` Promise.resolve ` 方法返回一个新的Promise对象,状态为` resolved ` 。
659
659
660
660
``` javascript
661
661
var p = Promise .resolve (' Hello' );
@@ -666,11 +666,11 @@ p.then(function (s){
666
666
// Hello
667
667
```
668
668
669
- 上面代码生成一个新的Promise对象的实例` p ` 。由于字符串` Hello ` 不属于异步操作(判断方法是字符串对象不具有then方法),返回Promise实例的状态从一生成就是` Resolved ` ,所以回调函数会立即执行。` Promise.resolve ` 方法的参数,会同时传给回调函数。
669
+ 上面代码生成一个新的Promise对象的实例` p ` 。由于字符串` Hello ` 不属于异步操作(判断方法是字符串对象不具有then方法),返回Promise实例的状态从一生成就是` resolved ` ,所以回调函数会立即执行。` Promise.resolve ` 方法的参数,会同时传给回调函数。
670
670
671
671
** (4)不带有任何参数**
672
672
673
- ` Promise.resolve ` 方法允许调用时不带参数,直接返回一个` Resolved ` 状态的Promise对象。
673
+ ` Promise.resolve ` 方法允许调用时不带参数,直接返回一个` resolved ` 状态的Promise对象。
674
674
675
675
所以,如果希望得到一个Promise对象,比较方便的方法就是直接调用` Promise.resolve ` 方法。
676
676
@@ -767,7 +767,7 @@ Promise.prototype.done = function (onFulfilled, onRejected) {
767
767
};
768
768
```
769
769
770
- 从上面代码可见,` done ` 方法的使用,可以像` then ` 方法那样用,提供` Fulfilled ` 和` Rejected ` 状态的回调函数,也可以不提供任何参数。但不管怎样,` done ` 都会捕捉到任何可能出现的错误,并向全局抛出。
770
+ 从上面代码可见,` done ` 方法的使用,可以像` then ` 方法那样用,提供` fulfilled ` 和` rejected ` 状态的回调函数,也可以不提供任何参数。但不管怎样,` done ` 都会捕捉到任何可能出现的错误,并向全局抛出。
771
771
772
772
### finally()
773
773
0 commit comments