Promise是JavaScript社区针对异步编程提出的一套解决方案,现已被纳入ES6的标准中。
Promise拥有三个状态:未完成态(pending)、完成态(fulfilled)、失败态(rejected ),其关系如下图:
graph LR; A(未完成态)-->B(完成态) A-->C(失败态)
Promise的使用
var promise = new Promise(function (resolve, reject) {
if (成功) {
resolve(result);
} else {
reject(error);
}
});
promise.then((result) => {
console.log("Success");
}, (error) => {
console.log("Error");
});
上述代码中,第一段实例化Promise得到promise变量,其构造函数接受一个函数作为参数,该函数用于决定在何时调用成功或失败的回调函数。这个参数函数有两个参数:resolve、reject,分别是成功的回调函数、失败的回调函数。
第二段代码中,使用Promise的成员方法then传入回调函数,其接受两个参数,分别为成功后的回调函数和失败后的回调函数(失败的回调函数为可选 )。
例如,读取一个文件:
const fs = require('fs');
var promise = new Promise((resolve, reject) => {
fs.readFile("a.txt", "utf8", function (error, data) {
if (error) {
reject(error);
} else {
resolve(data);
}
});
});
promise.then((data) => {
console.log(data);
}, (error) => {
console.log(error);
});
Promise的成员方法
then()
前面的实例已经使用到了then方法,其接受两个参数:
promise.then(resolve[, reject]);
@param Function resolve: 成功回调函数
@param Function reject: 失败回调函数]
@return Promise 新的Promise实例,并不是原来的Promise实例
then方法的作用是向Promise实例中添加状态改变时的回调函数。
因为then方法返回一个新的Promise实例,所以支持链式调用。
catch()
catch(callback)
@param Function callback: 异步操作中发生错误时的回调函数
@return Promise
catch(callback)的实际就是:
then(null, callback);
其用于指定发生错误时的回调函数。当Promise的状态变为resolved时,调用then方法传入的成功回调函数,当异步操作发生错误时,Promise的状态变为rejected时,调用catch传入的回调函数。另外,then方法指定的回调函数,如果在运行中抛出错误,也会被catch方法捕获。
finally()
finally方法中的代码不管最后Promise对象是什么状态都会执行。
finally(callback)
@param Function callback: 回调函数
@return Promise
其底层代码为:
Promise.prototype.finally = function (callback) {
let P = this.constructor;
return this.then(
value => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => { throw reason })
);
};
可见,finally也是通过then方法实现的。
all()
all(promiseArray)
@param Array promiseArray: Promise对象数组
@return Promise
只有当Promise数组中的所有实例的状态都变为resolved时,或者其中一个变为rejected时,才会执行回调函数。例如:
var firstPromise = new Promise((resolve, reject) => {
var res1 = 1;
console.log("res1:", res1);
return Promise.resolve(res1);
});
var secondPromise = new Promise((resolve, reject) => {
var res2 = 2;
console.log("res2:", res2);
return Promise.resolve(res2);
});
Promise.all([firstPromise, secondPromise])
.then(([res1, res2]) => {
console.log(res1);
console.log(res2);
});
上述代码中,当firstPromise和secondPromise的状态全部都为resolved时,执行后面的成功回调,当任意一个对象的状态为rejected时,执行后面的失败回调。
race()
与all方法一样,race方法接受一个Promise数组作为参数,与all不同的是,当race的参数数组中任意一个Promise对象的状态变为resolved时,后续回调执行。
Promise.resolve()
Promise.resolve()可以将现有对象转化为Promise对象。
Promise.resolve(params);
// 等价于
new Promise(params => resolve(params));
1、参数为thenable对象
thenable对象是指具有then方法的对象,Promise.resolve()会将该对象转化为Promise对象,然后立即执行该对象中的then方法,对象的状态就变为resolved。
2、参数为Promise实例
如果参数是一个Promise实例,Promise.resolve()将直接返回这个实例。
3、参数为其他值
参数作为成功回调函数的参数,返回一个状态为resolved的Promise对象
4、无参数
只返回一个resolved状态的Promise对象
Promise.reject()
返回一个rejected状态的Promise对象,参数作为后续方法的参数。