JavaScript Promise
一、Promise简介
Promise对象表示一个异步操作的最终状态(完成或失败),以及其返回的值。
1、语法
//new Promise(executor)
new Promise(function(resolve, reject){
	
});
参数executor是带有resolve和reject两个参数的函数,该函数在Promise构造函数执行时调用(executor函数在Promise构造函数返回新建的对象前被调用)。resolve和reject函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。
executor函数内部通常会执行一些异步操作,操作完成后可以调用resolve函数来将promise状态改成fulfilled,或者在发生错误时将它的状态改为rejected(此时executor函数的返回值将被忽略)。
2、状态
一个Promise对象有以下几种状态:
-  
pending(待定)初始状态,不是成功也不是失败状态。
 -  
fulfilled或resolved(完成)表示操作成功完成。
 -  
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(){
	
});
onFinally为Promise对象状态改变后执行的回调函数。由于无法知道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为一个可迭代对象,例如:Array或String。
此方法返回一个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
});