1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 18:32:22 +00:00

edit promise

This commit is contained in:
Ruan Yifeng 2015-05-21 15:56:39 +08:00
parent 863f5afbee
commit 81fe014df6

View File

@ -2,9 +2,11 @@
## 基本用法 ## 基本用法
ES6原生提供了Promise对象。所谓Promise对象就是代表了未来某个将要发生的事件通常是一个异步操作。它的好处在于有了Promise对象就可以将异步操作以同步操作的流程表达出来避免了层层嵌套的回调函数。此外Promise对象还提供了一整套完整的接口使得可以更加容易地控制异步操作。Promise对象的概念的详细解释请参考[《JavaScript标准参考教程》](http://javascript.ruanyifeng.com/) ES6原生提供了Promise对象。所谓Promise对象就是代表了某个未来才会知道结果的事件通常是一个异步操作并且这个事件提供统一的API可供进一步处理
ES6的Promise对象是一个构造函数用来生成Promise实例。下面是Promise对象的基本用法。 有了Promise对象就可以将异步操作以同步操作的流程表达出来避免了层层嵌套的回调函数。此外Promise对象提供的接口使得控制异步操作更加容易。Promise对象的概念的详细解释请参考[《JavaScript标准参考教程》](http://javascript.ruanyifeng.com/)。
ES6的Promise对象是一个构造函数用来生成Promise实例。
```javascript ```javascript
@ -24,9 +26,9 @@ promise.then(function(value) {
``` ```
上面代码表示Promise构造函数接受一个函数作为参数该函数的两个参数分别是resolve方法和reject方法。如果异步操作成功则用resolve方法将Promise对象的状态变为“成功”即从pending变为resolved如果异步操作失败则用reject方法将状态变为“失败”即从pending变为rejected 上面代码Promise构造函数接受一个函数作为参数该函数的两个参数分别是resolve方法和reject方法。如果异步操作成功则用resolve方法将Promise对象的状态,从“未完成”变为“成功”即从pending变为resolved如果异步操作失败则用reject方法将Promise对象的状态,从“未完成”变为“失败”即从pending变为rejected
promise实例生成以后可以用then方法分别指定resolve方法和reject方法的回调函数。 Promise实例生成以后可以用then方法分别指定resolve方法和reject方法的回调函数。
下面是一个使用Promise对象的简单例子。 下面是一个使用Promise对象的简单例子。
@ -44,7 +46,7 @@ timeout(100).then(() => {
``` ```
上面代码的timeout方法返回一个Promise实例对象表示一段时间以后改变自身状态从而触发then方法绑定的回调函数。 上面代码timeout方法返回一个Promise实例表示一段时间以后才会发生的结果。一旦Promise对象的状态变为resolved就会触发then方法绑定的回调函数。
下面是一个用Promise对象实现的Ajax操作的例子。 下面是一个用Promise对象实现的Ajax操作的例子。
@ -60,11 +62,11 @@ var getJSON = function(url) {
client.send(); client.send();
function handler() { function handler() {
if (this.status === 200) { if (this.status === 200) {
resolve(this.response); resolve(this.response);
} else { } else {
reject(new Error(this.statusText)); reject(new Error(this.statusText));
} }
}; };
}); });
@ -79,33 +81,35 @@ getJSON("/posts.json").then(function(json) {
``` ```
上面代码中resolve方法和reject方法调用时都带有参数。它们的参数会被传递给回调函数。reject方法的参数通常是Error对象的实例而resolve方法的参数除了正常的值以外还可能是另一个Promise实例比如像下面这样。 上面代码中getJSON是对XMLHttpRequest对象的封装用于发出一个针对JSON数据的HTTP请求并且返回一个Promise对象。需要注意的是在getJSON内部resolve方法和reject方法调用时都带有参数。
如果调用resolve方法和reject方法时带有参数那么它们的参数会被传递给回调函数。reject方法的参数通常是Error对象的实例表示抛出的错误resolve方法的参数除了正常的值以外还可能是另一个Promise实例表示异步操作的结果有可能是一个值也有可能是另一个异步操作比如像下面这样。
```javascript ```javascript
var p1 = new Promise(function(resolve, reject){ var p1 = new Promise(function(resolve, reject){
// ... some code // ...
}); });
var p2 = new Promise(function(resolve, reject){ var p2 = new Promise(function(resolve, reject){
// ... some code // ...
resolve(p1); resolve(p1);
}) })
``` ```
上面代码中p1和p2都是Promise的实例但是p2的resolve方法将p1作为参数这时p1的状态就会传递给p2。如果调用的时候p1的状态是pending那么p2的回调函数就会等待p1的状态改变如果p1的状态已经是fulfilled或者rejected那么p2的回调函数将会立刻执行。 上面代码中p1和p2都是Promise的实例但是p2的resolve方法将p1作为参数p1的状态就会传递给p2。
注意这时p1的状态决定了p2的状态。如果p1的状态是pending那么p2的回调函数就会等待p1的状态改变如果p1的状态已经是fulfilled或者rejected那么p2的回调函数将会立刻执行。
## Promise.prototype.then() ## Promise.prototype.then()
Promise.prototype.then方法返回的是一个新的Promise对象因此可以采用链式写法。 Promise.prototype.then方法返回的是一个新的Promise对象因此可以采用链式写法即then方法后面再调用另一个then方法
```javascript ```javascript
getJSON("/posts.json").then(function(json) { getJSON("/posts.json").then(function(json) {
return json.post; return json.post;
}).then(function(post) { }).then(function(post) {
// proceed // ...
}); });
``` ```
@ -119,12 +123,12 @@ getJSON("/posts.json").then(function(json) {
getJSON("/post/1.json").then(function(post) { getJSON("/post/1.json").then(function(post) {
return getJSON(post.commentURL); return getJSON(post.commentURL);
}).then(function(comments) { }).then(function(comments) {
// 对comments进行处理 // ...
}); });
``` ```
这种设计使得嵌套的异步操作,可以被很容易得改写,从回调函数的“横向发展”改为“向下发展” then方法还可以接受第二个参数表示Promise对象的状态变为rejected时的回调函数
## Promise.prototype.catch() ## Promise.prototype.catch()
@ -133,7 +137,7 @@ Promise.prototype.catch方法是`Promise.prototype.then(null, rejection)`的别
```javascript ```javascript
getJSON("/posts.json").then(function(posts) { getJSON("/posts.json").then(function(posts) {
// some code // ...
}).catch(function(error) { }).catch(function(error) {
// 处理前一个回调函数运行时发生的错误 // 处理前一个回调函数运行时发生的错误
console.log('发生错误!', error); console.log('发生错误!', error);
@ -157,7 +161,7 @@ promise.catch(function(error) { console.log(error) });
上面代码中Promise抛出一个错误就被catch方法指定的回调函数捕获。 上面代码中Promise抛出一个错误就被catch方法指定的回调函数捕获。
如果Promise状态已经变成“已完成”,再抛出错误是无效的。 如果Promise状态已经变成resolved,再抛出错误是无效的。
```javascript ```javascript
@ -223,6 +227,16 @@ promise.then(function(value) { console.log(value) });
上面代码中Promise指定在下一轮“事件循环”再抛出错误结果由于没有指定catch语句就冒泡到最外层成了未捕获的错误。 上面代码中Promise指定在下一轮“事件循环”再抛出错误结果由于没有指定catch语句就冒泡到最外层成了未捕获的错误。
Node.js有一个unhandledRejection事件专门监听未捕获的reject错误。
```javascript
process.on('unhandledRejection', function (err, p) {
console.error(err.stack)
});
```
上面代码中unhandledRejection事件的监听函数有两个参数第一个是错误对象第二个是报错的Promise实例它可以用来了解发生错误的环境信息。。
需要注意的是catch方法返回的还是一个Promise对象因此后面还可以接着调用then方法。 需要注意的是catch方法返回的还是一个Promise对象因此后面还可以接着调用then方法。
```javascript ```javascript