Skip to content

Commit 28b63f2

Browse files
committed
edit promise
1 parent f07d5c2 commit 28b63f2

File tree

1 file changed

+79
-8
lines changed

1 file changed

+79
-8
lines changed

docs/promise.md

Lines changed: 79 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ getJSON("/post/1.json").then(function(post) {
262262
263263
上面代码中,一共有三个Promise对象:一个由`getJSON`产生,两个由`then`产生。它们之中任何一个抛出的错误,都会被最后一个`catch`捕获。
264264
265-
一般来说,不要在`then`方法里面定义Rejection状态的回调函数(即`then`的第二个参数),总是使用`catch`方法。
265+
一般来说,不要在`then`方法里面定义Reject状态的回调函数(即`then`的第二个参数),总是使用`catch`方法。
266266
267267
```javascript
268268
// bad
@@ -324,7 +324,7 @@ process.on('unhandledRejection', function (err, p) {
324324
325325
上面代码中,`unhandledRejection`事件的监听函数有两个参数,第一个是错误对象,第二个是报错的Promise实例,它可以用来了解发生错误的环境信息。。
326326
327-
需要注意的是,catch方法返回的还是一个Promise对象,因此后面还可以接着调用then方法
327+
需要注意的是,`catch`方法返回的还是一个Promise对象,因此后面还可以接着调用`then`方法
328328
329329
```javascript
330330
var someAsyncThing = function() {
@@ -334,18 +334,31 @@ var someAsyncThing = function() {
334334
});
335335
};
336336
337-
someAsyncThing().then(function() {
338-
return someOtherAsyncThing();
339-
}).catch(function(error) {
337+
someAsyncThing()
338+
.catch(function(error) {
340339
console.log('oh no', error);
341-
}).then(function() {
340+
})
341+
.then(function() {
342342
console.log('carry on');
343343
});
344344
// oh no [ReferenceError: x is not defined]
345345
// carry on
346346
```
347347
348-
上面代码运行完`catch`方法指定的回调函数,会接着运行后面那个`then`方法指定的回调函数。
348+
上面代码运行完`catch`方法指定的回调函数,会接着运行后面那个`then`方法指定的回调函数。如果没有报错,则会跳过`catch`方法。
349+
350+
```javascript
351+
Promise.resolve()
352+
.catch(function(error) {
353+
console.log('oh no', error);
354+
})
355+
.then(function() {
356+
console.log('carry on');
357+
});
358+
// carry on
359+
```
360+
361+
上面的代码因为没有报错,跳过了`catch`方法,直接执行后面的`then`方法。此时,要是`then`方法里面报错,就与前面的`catch`无关了。
349362
350363
`catch`方法之中,还能再抛出错误。
351364
@@ -504,7 +517,65 @@ p.then(null, function (s){
504517
// 出错了
505518
```
506519
507-
上面代码生成一个Promise对象的实例p,状态为rejected,回调函数会立即执行。
520+
上面代码生成一个Promise对象的实例`p`,状态为`rejected`,回调函数会立即执行。
521+
522+
## 两个有用的附加方法
523+
524+
ES6的Promise API提供的方法不是很多,有些有用的方法可以自己部署。下面介绍如何部署两个不在ES6之中、但很有用的方法。
525+
526+
### done()
527+
528+
Promise对象的回调链,不管以`then`方法或`catch`方法结尾,要是最后一个方法抛出错误,都有可能无法漏掉(Promise内部的错误不会冒泡到全局)。因此,我们可以提供一个`done`方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。
529+
530+
```javascript
531+
asyncFunc()
532+
.then(f1)
533+
.catch(r1)
534+
.then(f2)
535+
.done();
536+
```
537+
538+
它的实现代码相当简单。
539+
540+
```javascript
541+
Promise.prototype.done = function (onFulfilled, onRejected) {
542+
this.then(onFulfilled, onRejected)
543+
.catch(function (reason) {
544+
// 抛出一个全局错误
545+
setTimeout(() => { throw reason }, 0);
546+
});
547+
};
548+
```
549+
550+
从上面代码可见,`done`方法的使用,可以像`then`方法那样用,提供`Fulfilled`和`Rejected`状态的回调函数,也可以不提供任何参数。但不管怎样,`done`都会捕捉到任何可能出现的错误,并向全局抛出。
551+
552+
### finally()
553+
554+
`finally`方法用于指定不管Promise对象最后状态如何,都会执行的操作。它与`done`方法的最大区别,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。
555+
556+
下面是一个例子,服务器使用Promise处理请求,然后使用`finally`方法关掉服务器。
557+
558+
```javascript
559+
server.listen(0)
560+
.then(function () {
561+
// run test
562+
})
563+
.finally(server.stop);
564+
```
565+
566+
它的实现也很简单。
567+
568+
```javascript
569+
Promise.prototype.finally = function (callback) {
570+
let P = this.constructor;
571+
return this.then(
572+
value => P.resolve(callback()).then(() => value),
573+
reason => P.resolve(callback()).then(() => { throw reason })
574+
);
575+
};
576+
```
577+
578+
上面代码中,不管前面的Promise是`fulfilled`还是`rejected`,都会执行回调函数`callback`。
508579
509580
## 应用
510581

0 commit comments

Comments
 (0)