要实现有序的异步操作,通常是一层加一层嵌套下去。
为了解决这个问题,ES6提出了Promise
的实现...
Promise 对象用于一个异步操作的最终完成(或失败)及其结果值的表示。简单点说,它就是用于处理异步操作的,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者停止后续操作。
它的一般表示形式为:
new Promise(
/* executor */
function(resolve, reject) {
if (/* success */) {
// ...执行代码
resolve();
} else { /* fail */
// ...执行代码
reject();
}
}
);
其中,Promise中的参数executor
是一个执行器函数,它有两个参数resolve
和reject
。它内部通常有一些异步操作,如果异步操作成功,则可以调用resolve()来将该实例的状态置为fulfilled
,即已完成的,如果一旦失败,可以调用reject()来将该实例的状态置为rejected
,即失败的。
我们可以把Promise对象看成是一条工厂的流水线,对于流水线来说,从它的工作职能上看,它只有三种状态,一个是初始状态(刚开机的时候),一个是加工产品成功,一个是加工产品失败(出现了某些故障)。同样对于Promise对象来说,它也有三种状态:
1.pending
初始状态,也称为未定状态,就是初始化Promise时,调用executor执行器函数后的状态。
2.fulfilled
完成状态,意味着异步操作成功。
3.rejected
失败状态,意味着异步操作失败。
如果有这样一个promise链:
p1().then(p2).then(p3)
.then(function(data) {
console.log('data: ' + data);
})
.catch(function(error) {
console.log('error: ' + error);
});
function p1() {
return new Promise(function(resolve, reject) {
console.log('p1 resolved');
resolve(123);
});
}
function p2() {
return new Promise(function(resolve, reject) {
console.log('p2 rejected');
reject(456);
});
}
function p3() {
return new Promise(function(resolve, reject) {
console.log('p3 resolved');
resolve(789);
});
}
上面这个例子,console.log结果会是这样:
1 p1 resolved
2 p2 rejected
3 error: 456
总之 : 在一个promise链中,只要任何一个promise被reject,promise链就被破坏了,reject之后的promise都不会再执行,而是直接调用.catch方法。
这也是为什么在standard practice中,一定要在最后加上 .catch
的原因。通过 .catch
能够清楚的判断出promise链在哪个环节出了问题。
A .Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject ,它们是两个函数 .
B . then方法可以接受两个回调函数作为参数,第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用
C .其中,第二个reject 函数是可选的,不一定要提供,Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。
Promise对象,可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
Promise.all([]) 全部加载成功 则返回所有resolve按顺序所集合的数组 有一个失败 则立即返回失败的reject 空数组 则直接成功
如果接受的是thenable对象,则会把他包装成promise对象,并立即执行该对象的then方法。
Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。