一、Promise简介

Promise对象表示一个异步操作的最终状态(完成或失败),以及其返回的值。

1、语法

//new Promise(executor)
new Promise(function(resolve, reject){
	
});

参数executor是带有resolvereject两个参数的函数,该函数在Promise构造函数执行时调用(executor函数在Promise构造函数返回新建的对象前被调用)。resolvereject函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。

executor函数内部通常会执行一些异步操作,操作完成后可以调用resolve函数来将promise状态改成fulfilled,或者在发生错误时将它的状态改为rejected(此时executor函数的返回值将被忽略)。

2、状态

一个Promise对象有以下几种状态:

  • pending(待定)

    初始状态,不是成功也不是失败状态。

  • fulfilledresolved(完成)

    表示操作成功完成。

  • rejected(失败)

    表示操作失败。

二、方法

1、原型方法

Promise.prototype.then(onFulfilled, onRejected)

var p = new Promise(function(resolve, reject){
	//...
});
p.then(function(value){
	//fulfillment
}, function(reason){
	//rejection
});

给当前Promise对象添加完成和失败时的回调函数,并返回新的Promise对象;该函数可以被链式调用。

第一个参数为Promise对象变为fulfilled状态时的回调函数,该函数有一个参数,其值为Promise对象完成时的值;第二个参数为Promise对象变为rejected状态时的回调函数,该函数也有一个参数,其值为Promise对象失败时的原因。

let p = new Promise((resolve, reject) => {
	resolve('Success!');
});
p.then((value)=>{
	console.log(value);//Success!
}, (reason)=>{
	console.log(reason);
});
let p = new Promise((resolve, reject) => {
	reject('Error!');
});
p.then((value)=>{
	console.log(value);
}, (reason)=>{
	console.log(reason);//Error!
});
  • catch()
Promise.prototype.catch(onRejected)

var p = new Promise(function(resolve, reject){
	//...
});
p.catch(function(reason){
	//rejection
});

此方法返回一个新的Promise对象,是处理失败时的情况,与Promise.prototype.then(undefined, onRejected)类似。

此方法的参数为当Promise对象的状态变为rejected时的回调函数,该函数有一个参数,其值为失败的原因。

如果onRejected函数抛出一个错误或返回一个rejected状态的Promise对象,则返回的Promise对象是被拒绝的rejected;否则,是被处理的resolved

let p = new Promise((resolve, reject)=>{
	resolve('Success');
});
p.then((value)=>{
	console.log("√", value);
	throw 'ERROR';
}).catch((reason)=>{
	console.log("×", reason);
}).then((value)=>{
	console.log('after a catch the chain is restored!');
}, (reason)=>{
	console.log('Not fired due to the catch');
});

输出:

√ Success
× ERROR
after a catch the chain is restored!

在异步函数中抛出的错误不会被catch()捕获到:

let p = new Promise((resolve, reject) => {
	setTimeout(()=>{
		throw 'Uncaught Exception!';
	}, 1000);
});
p.catch(reason=>{
	console.log('Will not be executed');
});

resolve()后面抛出的错误也会被忽略:

let p = new Promise((resolve, reject) => {
	resolve();
	throw 'Silenced Exception!';
});
p.catch(reason=>{
	console.log('Will not be executed');
});
  • finally()

此方法在Promise对象执行结束时调用,无论结果是完成或失败。在执行完then()catch()后,都会执行finally()

Promise.prototype.finally(onFinally)

var p = new Promise(function(resolve, reject){
	//...
});
p.finally(function(){
	
});

onFinallyPromise对象状态改变后执行的回调函数。由于无法知道Promise对象的最终状态,所以finally回调函数中不接收任何参数。

2、静态方法

语法:

Promise.resolve(thenable);
Promise.resolve(promise);
Promise.resolve(value);

此方法返回一个按给定值value解析后的Promise对象,如果value带有then方法(thenable),则返回的Promise对象会使用该value的最终状态(resolved/rejected/pending/settled);如果value本身就是Promise对象,则value作为此方法的返回值;否则返回一个以value为成功状态的的Promise对象。

从一个普通值中解析:

let p = Promise.resolve(123);
p.then((value)=>{
	console.log(value);//123
});

p = Promise.resolve('Success');
p.then((value)=>{
	console.log(value);//Success
});

p = Promise.resolve([1, 2, 3]);
p.then(value=>{
	console.log(value);//[1, 2, 3]
});

从一个Promise对象中解析:

let original = Promise.resolve(66);
let p = Promise.resolve(original);
p.then((value)=>{
	console.log(`value: ${value}`);
});
console.log(`original === p : ${original === p} `);

输出:

original === p : true 
value: 66

thenable对象中解析:

let thenable = {
	then: (onFulfill, onReject)=>{
		onFulfill('fulfilled');
	}
};
let p = Promise.resolve(thenable);
console.log(p instanceof Promise);//true

p.then(value=>{
	console.log(value);//fulfilled
}, error=>{
	//Will not be executed
});

如果在resolve之前抛出错误,则Promise对象被reject,执行失败回调函数;相反,在resolve之后抛出错误,Promise对象被resolve,执行成功回调函数。

let thenable = {
	then: (onFulfill, onReject)=>{
		throw new TypeError('Throwing');
		resolve('resolving');
	}
};
let p = Promise.resolve(thenable);
p.then(v=>{
	//Will not be executed
}, e=>{
	console.log(e);//TypeError: Throwing  at Object.then (<anonymous>:3:9)
});
Promise.reject(reason);

此方法返回一个参数为失败原因(reason)的Promise对象(状态为rejected)。

let p = Promise.reject('wrong');
//等价于
let p = new Promise((resolve, reject) => reject('wrong'));

p.then(function(result){
	//Will not be executed
}, function(reason){
	console.log(reason);//wrong
});

此方法的参数会原封不动的作为reject的原因(reason):

let thenable = {
	then(resolve, reject){
		reject('wrong');
	}
};
Promise.reject(thenable).catch(reason => {
	console.log(reason === thenable);//true
});

Promise.reject(new Error('fail')).catch(reason => console.log(reason));
//Error: fail
//   at <anonymous>:1:16

参数iterable为一个可迭代对象,例如:ArrayString

此方法返回一个Promise对象,该对象在iterable参数内的所有Promise对象都完成(resolved)或者参数中不包含Promise对象时执行完成回调函数;如果参数中Promise对象有一个失败(rejected),则此Promise对象失败,执行失败时回调函数(不管其它Promise对象是否完成);失败的原因为第一个失败的Promise的原因。

let p1 = Promise.resolve(3);
let p2 = 1234;
let p3 = new Promise((resolve, reject) => {
	setTimeout(resolve, 2000, 'Hello World!');
});
Promise.all([p1, p2, p3]).then(values => {
	console.log(values);
});

如果iterable为空,此方法同步返回一个已完成(resolved)状态的Promise对象;

let p = Promise.all([]);
console.log(p);//Promise {<resolved>: Array(0)}

如果iterable中所有Promise对象都变为完成状态或都iterable中没有Promise对象,则此方法异步的变为完成状态。

let arr = [Promise.resolve(true), Promise.resolve(2), Promise.resolve('a')];
let p = Promise.all(arr);
console.log(p);//Promise {<pending>}
setTimeout(()=>{
	console.log(p);//Promise {<resolved>: Array(3)}
});

如果iterable中有一个失败,则此方法会异步的将失败结果传给失败的Promise对象的失败回调函数。

let reject = Promise.reject('abc').catch((reason)=>{
	console.log(reason);//abc
});
let arr = [Promise.resolve(123), reject];
let p = Promise.all(arr);
console.log(p);//Promise {<pending>}
setTimeout(()=>{
	console.log(p);//Promise {<resolved>: Array(2)}
});
let p1 = new Promise((resolve, reject)=>{
	setTimeout(resolve, 1000, 'one');
});
let p2 = new Promise((resolve, reject)=>{
	setTimeout(reject, 2000, 'two');
});
let p3 = new Promise((resolve, reject) => {
	setTimeout(resolve, 3000, 'three');
});
let p = Promise.all([p1, p2, p3]).then(vlaues => {
	console.log(values);
}, reason => {
	console.log(reason);//two
});
console.log(p);//Promise {<pending>}
setTimeout(()=>{
	console.log(p);//Promise {<resolved>: undefined}
}, 2500);

此方法返回一个Promise对象,一旦iterable中的某个Promise对象被解决或者拒绝,则返回的Promise对象就会被异步的解决或拒绝。如果iterable是空的,则返回的Promise对象永远是等待状态。如果iterable中是一个或多个已解决或拒绝的Promise对象,则返回值为第一个完成的Promise对象。

let arr = [Promise.resolve(1), Promise.resolve('a')];
let p = Promise.race(arr);
console.log(p);//Promise {<pending>}
setTimeout(()=>{
	console.log(p);//Promise {<resolved>: 1}
});
let p1 = new Promise((resolve, reject) => {
	setTimeout(resolve, 1000, 'one');
});
let p2 = new Promise((resolve, reject) => {
	setTimeout(resolve, 2000, 'two');
});
let p3 = new Promise((resolve, reject) => {
	setTimeout(reject, 500, 'three');
});

Promise.race([p1, p2]).then((result)=>{
	console.log(result);//one
}, (reason) => {
	console.log(reason);
});

Promise.race([p1, p3]).catch((reason) => {
	console.log(reason);//three
});
附: