1: 何为Promise
Promise是抽象异步处理对象以及对其对象进行各种操作的组件,是基于并列/并行处理设计的一种编程语言。
说到基于JavaScript的异步处理,大多数都会想到利用回调函数。Node.js等则规定在JavaScript的回调函数的第一个参数为error对象,这也是他的一个惯例。
而Promise则是把类似的异步处理对象和处理规则进行规范化, 并按照采用统一的接口来编写,而采取规定方法之外的写法都会出错。
如:
var promise = getAsyncPromise("fileA.txt"); //返回promise对象
promise.then(function(result){ // 获取文件内容成功时的处理}).catch(function(error){ // 获取文件内容失败时的处理}); //通过promise对象调用then(成功的回调),catch(失败的回调)
也就是说,除promise对象规定的方法(这里的then 或catch)以外的方法都是不可以使用的,而不会像回调函数方式那样可以自己自由的定义回调函数的参数,而必须严格遵守固定、统一的编程方式来编写代码。
所以,promise的功能是可以将复杂的异步处理轻松地进行模式化, 这也可以说得上是使用promise的理由之一。
2:构造Constructor
要想创建一个promise对象、可以使用new来调用Promise的构造器来进行实例化。
var promise = new Promise(function(resolve, reject) {
// 异步处理 done()
// 处理结束后、成功调用resolve ,失败调用 reject
});
对通过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) 应该是个更好的选择。
其实可以理解为 .catch只是 promise.then(undefined, onRejected) 的别名而已。
一般说来,使用.catch来将resolve和reject处理分开来写是比较推荐的做法。
创建promise对象的流程如下所示:
(1):new Pormise(fn) 返回一个promise对象。
(2):在fn中指定异步等处理
• 处理结果正常的话,调用resolve(处理结果值)
• 处理结果错误的话,调用reject(Error对象)
3:静态方法
像 Promise 这样的全局对象还拥有一些静态方法
包括 Promise.all() 还有 Promise.resolve() 等在内,主要都是一些对Promise进行操作的辅助方法
4:Promise的工作流程
function asyncFunction() {
return new Promise(function (resolve, reject) { //通过new Promise返回一个promise对象
setTimeout(function () {
resolve('Async Hello world'); }, 16);
});
} (1)
asyncFunction().then(function (value) { //通过promise对象来调用then,catch方法
console.log(value); // => 'Async Hello world'
}).catch(function (error) {
console.log(error);
}); (2)
(1)new Promise构造器之后会返回一个promise对象。
(2)为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);}); // then(onFullfilled, onRejected)
5:Promise的状态
用new Promise实例化的promise对象有以下三个状态。
"has-resolution" - Fulfilledresolve(成功)时。此时会调 OnFullfilled
"has-rejection" - Rejectedreject(失败)时。此时会调 OnRejected
"unresolved" - Pending既不是resolve也不是reject的状态。也就是promise对象刚被创建后的初始化状态等。
以上术语,基本会基于 Promises/A+13中 Pending 、 Fulfilled 、 Rejected 的状态名称进行讲诉。
promise对象的状态,从Pending转换为Fulfilled或Rejected之后,这个promise对象的状态就不会再发生任何变化。