1.2. Promise简介
在 ES6 Promises 标准中定义的API还不是很多。
目前大致有下面三种类型。
Constructor
Promise类似于 XMLHttpRequest
,从构造函数 Promise
来创建一个新建新promise
对象作为接口。
要想创建一个promise对象、可以使用new
来调用Promise
的构造器来进行实例化。
var promise = new Promise(function(resolve, reject) {
// 异步处理
// 处理结束后、调用resolve 或 reject
});
Instance Method
对通过new生成的promise对象为了设置其值在 resolve(成功) / reject(失败)时调用的回调函数 可以使用promise.then()
实例方法。
promise.then(onFulfilled, onRejected)
resolve(成功)时
onFulfilled
会被调用
reject(失败)时
onRejected
会被调用
onFulfilled
、onRejected
两个都为可选参数。
promise.then
成功和失败时都可以使用。 另外在只想对异常进行处理时可以采用 promise.then(undefined, onRejected)
这种方式,只指定reject时的回调函数即可。 不过这种情况下 promise.catch(onRejected)
应该是个更好的选择。
promise.catch(onRejected)
Static Method
像 Promise
这样的全局对象还拥有一些静态方法。
包括 Promise.all()
还有 Promise.resolve()
等在内,主要都是一些对Promise进行操作的辅助方法。
1.2.1. Promise workflow
我们先来看一看下面的示例代码。
promise-workflow.js
function asyncFunction() {
(1)
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('Async Hello world');
}, 16);
});
}
(2)
asyncFunction().then(function (value) {
console.log(value); // => 'Async Hello world'
}).catch(function (error) {
console.log(error);
});
1 | new Promise构造器之后,会返回一个promise对象 |
2 | <1>为promise对象用设置 .then 调用返回值时的回调函数。 |
asyncFunction
这个函数会返回promise对象, 对于这个promise对象,我们调用它的 then
方法来设置resolve后的回调函数, catch
方法来设置发生错误时的回调函数。
该promise对象会在setTimeout之后的16ms时被resolve, 这时 then
的回调函数会被调用,并输出 'Async Hello world'
。
在这种情况下 catch
的回调函数并不会被执行(因为promise返回了resolve), 不过如果运行环境没有提供 setTimeout
函数的话,那么上面代码在执行中就会产生异常,在 catch
中设置的回调函数就会被执行。
当然,像promise.then(onFulfilled, onRejected)
的方法声明一样, 如果不使用catch
方法只使用 then
方法的话,如下所示的代码也能完成相同的工作。
asyncFunction().then(function (value) {
console.log(value);
}, function (error) {
console.log(error);
});
1.2.2. Promise的状态
我们已经大概了解了Promise的处理流程,接下来让我们来稍微整理一下Promise的状态。
用new Promise
实例化的promise对象有以下三个状态。
“has-resolution” - Fulfilled
resolve(成功)时。此时会调用 onFulfilled
“has-rejection” - Rejected
reject(失败)时。此时会调用 onRejected
“unresolved” - Pending
既不是resolve也不是reject的状态。也就是promise对象刚被创建后的初始化状态等
关于上面这三种状态的读法,其中 左侧为在 ES6 Promises 规范中定义的术语, 而右侧则是在 Promises/A+ 中描述状态的术语。
基本上状态在代码中是不会涉及到的,所以名称也无需太在意。 在这本书中,我们会基于 Promises/A+ 中 Pending 、 Fulfilled 、 Rejected 的状态名称进行讲述。
Figure 1. promise states
在 ECMAScript Language Specification ECMA-262 6th Edition – DRAFT 中 |
到此在本文中我们已经介绍了promise所有的三种状态。
promise对象的状态,从Pending转换为Fulfilled或Rejected之后, 这个promise对象的状态就不会再发生任何变化。
也就是说,Promise与Event等不同,在.then
后执行的函数可以肯定地说只会被调用一次。
另外,Fulfilled和Rejected这两个中的任一状态都可以表示为Settled(不变的)。
Settled
resolve(成功) 或 reject(失败)。
从Pending和Settled的对称关系来看,Promise状态的种类/迁移是非常简单易懂的。
当promise的对象状态发生变化时,用.then
来定义只会被调用一次的函数。
JavaScript Promises - Thinking Sync in an Async World // Speaker Deck 这个ppt中有关于Promise状态迁移的非常容易理解的说明。 |