<div class="blogpost-body" id="cnblogs_post_body">
<h1>Promise 对象</h1>
<p>转载:http://wiki.jikexueyuan.com/project/es6/promise.html</p>
<h2 id="704f29e0e2e8a147241a7276fc072102">基本用法</h2>
<p>ES6 原生提供了 Promise 对象。所谓 Promise 对象,就是代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。</p>
<p>有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供的接口,使得控制异步操作更加容易。Promise 对象的概念的详细解释,请参考<a href="http://javascript.ruanyifeng.com/">《JavaScript标准参考教程》</a>。</p>
<p>ES6 的 Promise 对象是一个构造函数,用来生成 Promise 实例。</p>
<div class="cnblogs_Highlighter">
<pre class="blockcode"><code class="language-javascript">var promise = new Promise(function(resolve, reject) {
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(value) {
// success
}, function(value) {
// failure
});
</code></pre>
</div>
<p> </p>
<p>上面代码中,Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 方法和 reject 方法。如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从“未完成”变为“成功”(即从 pending 变为 resolved);如果异步操作失败,则用 reject 方法将 Promise 对象的状态,从“未完成”变为“失败”(即从 pending 变为 rejected)。</p>
<p>Promise 实例生成以后,可以用 then 方法分别指定 resolve 方法和 reject 方法的回调函数。</p>
<p>下面是一个使用 Promise 对象的简单例子。</p>
<div class="cnblogs_Highlighter">
<pre class="blockcode"><code class="language-javascript">function timeout(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
timeout(100).then(() => {
console.log('done');
});
</code></pre>
</div>
<p> </p>
<p>上面代码中,timeout 方法返回一个 Promise 实例,表示一段时间以后才会发生的结果。一旦 Promise 对象的状态变为 resolved,就会触发 then 方法绑定的回调函数。</p>
<p>下面是一个用 Promise 对象实现的 Ajax 操作的例子。</p>
<div class="cnblogs_Highlighter">
<pre class="blockcode"><code class="language-javascript">var getJSON = function(url) {
var promise = new Promise(function(resolve, reject){
var client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function handler() {
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
});
return promise;
};
getJSON("/posts.json").then(function(json) {
console.log('Contents: ' + json);
}, function(error) {
console.error('出错了', error);
});
</code></pre>
</div>
<p> </p>
<p>上面代码中,getJSON 是对 XMLHttpRequest 对象的封装,用于发出一个针对 JSON 数据的 HTTP 请求,并且返回一个 Promise 对象。需要注意的是,在 getJSON 内部,resolve 方法和 reject 方法调用时,都带有参数。</p>
<p>如果调用 resolve 方法和 reject 方法时带有参数,那么它们的参数会被传递给回调函数。reject 方法的参数通常是 Error 对象的实例,表示抛出的错误;resolve 方法的参数除了正常的值以外,还可能是另一个 Promise 实例,表示异步操作的结果有可能是一个值,也有可能是另一个异步操作,比如像下面这样。</p>
<div class="cnblogs_Highlighter">
<pre class="blockcode"><code class="language-javascript">var p1 = new Promise(function(resolve, reject){
// ...
});
var p2 = new Promise(function(resolve, reject){
// ...
resolve(p1);
})
</code></pre>
</div>
<p> </p>
<p>上面代码中,p1 和 p2 都是 Promise 的实例,但是 p2 的 resolve 方法将 p1 作为参数,p1 的状态就会传递给 p2。</p>
<p>注意,这时 p1 的状态决定了 p2 的状态。如果 p1 的状态是 pending,那么 p2 的回调函数就会等待 p1 的状态改变;如果 p1 的状态已经是 fulfilled 或者 rejected,那么 p2 的回调函数将会立刻执行。</p>
<h2 id="b267cd07b3da24f2efa55b955f21ef77">Promise.prototype.then()</h2>
<p>Promise.prototype.then 方法返回的是一个新的Promise对象,因此可以采用链式写法,即then方法后面再调用另一个then方法。</p>
<div class="cnblogs_Highlighter">
<pre class="blockcode"><code class="language-javascript">getJSON("/posts.json").then(function(json) {
return json.post;
}).then(function(post) {
// ...
});
</code></pre>
</div>
<p> </p>
<p>上面的代码使用then方 |
|