一、静态方法
Promise有四个静态方法,分别是resolve()、reject()、all()和race(),本节将着重分析这几个方法的功能和特点。
1)Promise.resolve()
此方法有一个可选的参数,参数的类型会影响它的返回值,具体可分为三种情况(如下所列),其中有两种情况会创建一个新的已处理的Promise实例,还有一种情况会返回这个参数。
(1)当参数为空或非thenable时,返回一个新的状态为fulfilled的Promise。
(2)当参数为thenable时,返回一个新的Promise,而它的状态由自身的then()方法控制,具体细节已在之前的thenable一节做过说明。
(3)当参数为Promise时,将不做修改,直接返回这个Promise。
下面用一个例子演示这三种情况,注意观察Promise的then()方法的第一个回调函数中接收到的决议结果。
let tha = {
then(resolve, reject) {
resolve("thenable");
}
};
//参数为空
Promise.resolve().then(function(value) {
console.log(value); //undefined
});
//参数为非thenable
Promise.resolve("string").then(function(value) {
console.log(value); //"string"
});
//参数为thenable
Promise.resolve(tha).then(function(value) {
console.log(value); //"thenable"
});
//参数为Promise
Promise.resolve(new Promise(function(resolve) {
resolve("Promise");
})).then(function(value) {
console.log(value); //"Promise"
});
2)Promise.reject()
此方法能接收一个参数,表示拒绝理由,它的返回值是一个新的已拒绝的Promise实例。与Promise.resolve()不同,Promise.reject()中所有类型的参数都会原封不动的传递给后续的已拒绝的回调函数,如下代码所示。
Promise.reject("rejected").catch(function (reason) {
console.log(reason); //"rejected"
});
var p = Promise.resolve();
Promise.reject(p).catch(function (reason) {
reason === p; //true
});
第一次调用Promise.reject()的参数是一个字符串,第二次的参数是一个Promise,catch()方法中的回调函数接收到的正是这两个参数。
3)Promise.all()
此方法和接下来要讲解的Promise.race()都可用来监控多个Promise,当它们的状态发生变化时,这两个方法会给出不同的处理方式。
Promise.all()能接收一个可迭代对象,其中可迭代对象中的成员必须是Promise,如果是字符串、thenable等非Promise的值,那么会自动调用Promise.resolve()转换成Promise。Promise.all()的返回值是一个新的Promise实例,当参数中的成员为空时,其状态为fulfilled;而当参数不为空时,其状态由可迭代对象中的成员决定,具体分为两种情况。
(1)当可迭代对象中的所有成员都是已完成的Promise时,新的Promise的状态为fulfilled。而各个成员的决议结果会组成一个数组,传递给后续的已完成的回调函数,如下所示。
var p1 = Promise.resolve(200),
p2 = "fulfilled";
Promise.all([p1, p2]).then(function (value) {
console.log(value); //[200, "fulfilled"]
});
(2)当可迭代对象中的成员有一个是已拒绝的Promise时,新的Promise的状态为rejected。并且只会处理到这个已拒绝的成员,接下来的成员都会被忽略,其决议结果会传递给后续的已拒绝的回调函数,如下所示。
var p1 = Promise.reject("error"),
p2 = "fulfilled";
Promise.all([p1, p2]).catch(function (reason) {
console.log(reason); //"error"
});
4)Promise.race()
此方法和Promise.all()有很多相似的地方,如下所列。
(1)能接收一个可迭代对象。
(2)成员必须是Promise,对于非Promise的值要用Promise.resolve()做转换。
(3)返回值是一个新的Promise实例。
新的Promise实例的状态也与方法的参数有关,当参数的成员为空时,其状态为pending;当参数不为空时,其状态是最先被处理的成员的状态,并且此成员的决议结果会传递给后续相应的回调函数,如下代码所示。
var p1 = new Promise(function(resolve) {
setTimeout(() => {
resolve("fulfilled");
}, 200);
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(() => {
reject("rejected");
}, 100);
});
Promise.race([p1, p2]).catch(function (reason) {
console.log(reason); //"rejected"
});
在p1和p2的执行器中都有一个定时器。由于后者的定时器会先执行,因此通过调用Promise.race([p1, p2])得到的Promise实例,其状态和p2的相同,而p2的决议结果会作为拒绝理由被catch()方法中的回调函数接收。
根据前面的分析可以得出,Promise.all()能处理一个或多个受监控的Promise,而Promise.race()只能处理其中的一个。