promise的作用
将异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。 这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者。
promise的状态
- 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled): 意味着操作成功完成。
- 已拒绝(rejected): 意味着操作失败。
promise的链式调用
可以用 promise.then()
,promise.catch()
和 promise.finally()
这些方法将进一步的操作与一个变为已敲定状态的 promise 关联起来。这些方法还会返回一个新生成的 promise 对象,这个对象可以被非强制性的用来做链式调用,就像这样:
1、(需要马上处理一个错误,最好使用此方式)
const myPromise =
(new Promise(myExecutorFunc))
.then(handleFulfilledA,handleRejectedA)
.then(handleFulfilledB,handleRejectedB)
.then(handleFulfilledC,handleRejectedC);
2、(在没有迫切需要的情况下,可以在最后一个.catch() 语句时再进行错误处理,这种做法更加简单。)
const myPromise =
(new Promise(myExecutorFunc))
.then(handleFulfilledA)
.then(handleFulfilledB)
.then(handleFulfilledC)
.catch(handleRejectedAny);
promise的静态方法
Promise.all()
通常在启动多个异步任务并发运行并为其结果创建promise之后使用,以便可以等待所有任务完成。
语法
Promise.all(iterable);
参数
- iterable
返回值
- 如果传入的参数是一个空的可迭代对象,则返回一个**已完成(already resolved)**状态的
Promise
。- 如果传入的参数不包含任何
promise
,则返回一个异步完成(asynchronously resolved)Promise
。注意:Google Chrome 58 在这种情况下返回一个**已完成(already resolved)**状态的Promise
。- 其它情况下返回一个处理中(pending)的
Promise
。这个返回的promise
之后会在所有的promise
都完成或有一个promise
失败时异步地变为完成或失败。 见下方关于“Promise.all 的异步或同步”示例。返回值将会按照参数内的promise
顺序排列,而不是由调用promise
的完成顺序决定。说明
此方法适用于集合多个
promise
的返回结果。
在任何情况下,Promise.all
返回的promise
的完成状态的结果都是一个数组,它包含所有的传入迭代参数对象的值(也包括非promise
值)。失败/拒绝(Rejection):
如果传入的promise
中有一个失败(rejected),Promise.all
异步地将失败的那个结果给失败状态的回调函数,而不管其它promise
是否完成。
示例
Promise.all
等待所有都完成(或第一个失败)。 适用于并发执行的情况
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, "foo"]
});
注意:如果参数中包含非 promise
值,这些值将被忽略,但仍然会被放在返回数组中(如果 promise
完成的话;promise完成失败的话只会返回失败的(reject)promise类型的数据)
// 这将被视为传递的iterable为空,因此返回所有类型的数据
var p = Promise.all([1,2,3]);
// 这将被视为传递的iterable只包含值为“444”的已解析promise,因此返回所有类型的数据
var p2 = Promise.all([1,2,3, Promise.resolve(444)]);
// 这将被视为传递的iterable只包含值为“555”的执行失败的promise数据,因此执行失败只返回promise类型数据
var p3 = Promise.all([1,2,3, Promise.reject(555)]);
// 使用setTimeout,我们可以在堆栈为空之后执行代码
setTimeout(function(){
console.log(p);
console.log(p2);
console.log(p3);
});
// logs
// Promise { <state>: "fulfilled", <value>: Array[3] }
// Promise { <state>: "fulfilled", <value>: Array[4] }
// Promise { <state>: "rejected", <reason>: 555 }
异步同步(如果传入的可迭代对象是空的,就是同步)
传入的参数中有执行失败的情况
// 将异步完成的promise数据作为参数
var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];
var p = Promise.all(resolvedPromisesArray);
// 输出此时p的值
console.log(p);
// 使用setTimeout,我们可以在堆栈为空之后执行代码
setTimeout(function(){
console.log('the stack is now empty');
console.log(p);
});
// logs, in order:
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: Array[2] }
promise.all执行失败
var mixedPromisesArray = [Promise.resolve(33), Promise.reject(44)];
var p = Promise.all(mixedPromisesArray);
console.log(p);
setTimeout(function(){
console.log('the stack is now empty');
console.log(p);
});
// logs
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "rejected", <reason>: 44 }
同步情况
var p = Promise.all([]); //将立即解决
var p2 = Promise.all([1337, "hi"]); // 非promise类型的值将被忽略,但返回时将以异步方式完成
console.log(p);
console.log(p2)
setTimeout(function(){
console.log('the stack is now empty');
console.log(p2);
});
// logs
// Promise { <state>: "fulfilled", <value>: Array[0] }
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: Array[2] }
快速返回失败行为,Promise.all
在任意一个传入的 promise
失败时返回失败。例如,如果你传入的 promise
中,有四个 promise
在一定的时间之后调用成功函数,有一个立即调用失败函数,那么 Promise.all
将立即变为失败。
var p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'one');
});
var p2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, 'two');
});
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, 'three');
});
var p4 = new Promise((resolve, reject) => {
setTimeout(resolve, 4000, 'four');
});
var p5 = new Promise((resolve, reject) => {
reject('reject');
});
Promise.all([p1, p2, p3, p4, p5]).then(values => {
console.log(values);
}, reason => {
console.log(reason)
});
//From console:
//"reject"
//You can also use .catch
Promise.all([p1, p2, p3, p4, p5]).then(values => {
console.log(values);
}).catch(reason => {
console.log(reason)
});
//From console:
//"reject"
promise.allSettled()
当有多个彼此不依赖的异步任务成功完成时,或者总是想知道每个promise
的结果时,通常使用它。
相比之下,Promise.all()
更适合彼此相互依赖或者在其中任何一个reject
时立即结束。
句法
Promise.allSettled(iterable);
参数
返回值
一旦所指定的 promises 集合中每一个 promise 已经完成,无论是成功的达成或被拒绝,未决议的
Promise
将被异步完成。那时,所返回的 promise 的处理器将传入一个数组作为输入,该数组包含原始 promises 集中每个 promise 的结果。对于每个结果对象,都有一个
status
字符串。如果它的值为fulfilled
,则结果对象上存在一个value
。如果值为rejected
,则存在一个reason
(异常错误) 。value(或 reason )反映了每个 promise 决议(或拒绝)的值。
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];
Promise.allSettled(promises).
then((results) => results.forEach((result) => console.log(result)));
// expected output:
//> Object { status: "fulfilled", value: 3 }
//> Object { status: "rejected", reason: "foo" }
promise.all()和promise.allSettled()的对比
Promise.allSettled()
方法返回一个在所有给定的promise都已经fulfilled
或rejected
后的promise,并带有一个对象数组,每个对象表示对应的promise结果。有多个彼此不依赖的异步任务成功完成时,或者想知道每个
promise
的结果时,通常使用它。相比之下,
Promise.all()
更适合彼此相互依赖或者在其中任何一个reject
时立即结束。简单的来说就是
Promise.allSettled()
返回所有的执行结果返回值类型为对象数组,Promise.all()
,其中任何一个promise参数reject
时立即结束,返回错误原因。
promise.any()
Promise.any()
接收一个Promise
可迭代对象,只要其中的一个 promise
成功,就返回那个已经成功的 promise
。如果可迭代对象中没有一个 promise
成功(即所有的 promises
都失败/拒绝),就返回一个失败的 promise
和AggregateError
类型的实例,它是 Error
的一个子类,用于把单一的错误集合在一起。本质上,这个方法和Promise.all()
是相反的。
语法
Promise.any(iterable);
参数
返回值
- 如果传入的参数是一个空的可迭代对象,则返回一个 已失败(already rejected) 状态的 Promise。
- 如果传入的参数不包含任何
promise
,则返回一个 异步完成 (asynchronously resolved)的 Promise。- 其他情况下都会返回一个处理中(pending) 的 Promise。 只要传入的迭代对象中的任何一个
promise
变成成功(resolve)状态,或者其中的所有的promises
都失败,那么返回的promise
就会 异步地(当调用栈为空时) 变成成功/失败(resolved/reject)状态。注意
这个方法用于返回第一个成功的
promise
。只要有一个promise
成功此方法就会终止,它不会等待其他的promise
全部完成。promise执行成功时只会返回第一个执行成功的成功值
这个方法将会忽略掉所有被拒绝的
promise
,直到第一个promise
成功。
示例
忽略掉所有被拒绝的 promise
,直到第一个 promise
成功。
const pErr = new Promise((resolve, reject) => {
reject("总是失败");
});
const pSlow = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "最终完成");
});
const pFast = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "很快完成");
});
Promise.any([pErr, pSlow, pFast]).then((value) => {
console.log(value);
// pFast fulfils first
})
// 输出: "很快完成"
所有的promise都执行失败
const pErr = new Promise((resolve, reject) => {
reject('总是失败');
});
const aErr = new Promise((resolve, reject) => {
reject('总是失败');
});
Promise.any([pErr,aErr]).catch((err) => {
console.log(err instanceof AggregateError); // true
console.log(err.errors);
})
// 输出: ["总是失败", "总是失败"]
promise.race()
Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,就会返回一个promise,状态由执行结果决定。
语法
Promise.race(iterable);
参数
返回值
一个待定的
Promise
只要给定的迭代中的一个promise解决或拒绝,就采用第一个promise的值作为它的值,从而异步地解析或拒绝(一旦堆栈为空)。描述
race
函数返回一个Promise
,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的方式是两个中的哪个。如果传的迭代是空的,则返回的 promise 将永远等待。
如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,则
Promise.race
将解析为迭代中找到的第一个值。
promise.race()的异步性
//将已经完成的promise类型数据作为参数
var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];
var p = Promise.race(resolvedPromisesArray);
//输出p当前的状态
console.log(p);
// 使用setTimeout,我们可以在堆栈为空之后执行代码
setTimeout(function(){
console.log('the stack is now empty');
console.log(p);
});
// logs, in order:
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: 33 }
使用promise.race()和setTimeout的栗子
var p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, "one");
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, "two");
});
Promise.race([p1, p2]).then(function(value) {
console.log(value); // "two"
// 两个都完成,但 p2 更快
});
var p3 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, "three");
});
var p4 = new Promise(function(resolve, reject) {
setTimeout(reject, 500, "four");
});
Promise.race([p3, p4]).then(function(value) {
console.log(value); // "three"
// p3 更快,所以它完成了
}, function(reason) {
// 未被调用
});
var p5 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, "five");
});
var p6 = new Promise(function(resolve, reject) {
setTimeout(reject, 100, "six");
});
Promise.race([p5, p6]).then(function(value) {
// 未被调用
}, function(reason) {
console.log(reason); // "six"
// p6 更快,所以它失败了
});