需要等待多个 Promise 执行完毕时,使用 Promise.all() 或者 Promise.race() 。
Promise.all
异步执行,快速失败。(只要一个失败,立即停止)
Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve); 如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果
代码一:
let p1 = new Promise((resolve, reject) => {setTimeout(resolve, 1000, 'ok1');});let p2 = new Promise((resolve, reject) => {resolve('ok2')});let p3 = new Promise((resolve, reject) => {setTimeout(reject, 4000, 'fail1');});let p4 = Promise.reject('fail2');let fn = function(ps) {Promise.all(ps).then((result) => {console.log(result);}).catch((error) => {console.log(error);})};fn([p1, p2, p3, p4]); // --> fail2fn([p1, p2, p3]); // --> fail1fn([p1, p2]); // --> ["ok1", "ok2"] , 返回结果数组和入参数组顺序一致,一一对应fn([p3, p4]); // --> fail2
从上面的测试可以看出,Promise.all() 只要有一个 失败,立即 catch() 。全部 成功 时,才会 then() 。
那么,如果想知道哪些成功,哪些失败呢?
代码二:
let fn = function(ps) {Promise.all((function(pList) {// Array.map(function(value)) 返回所有元素用方法处理过的新数组,方法按照原始数组元素顺序处理return pList.map(promise => promise.then((success) => ({success}), (error) => ({error})));})(ps)).then(res => {console.log(res);if(res.length === ps.length) {console.log('complete');}}, err => {console.log(err)});};fn([p1, p2, p3, p4]); // 结果1fn([p1, p2, p3]);fn([p1, p2]);fn([p3, p4]);
结果1 为:
[{success: "ok1"},{success: "ok2"},{error: "fail1"},{error: "fail2"}]complete
其他结果类似,都是在全部执行完毕后,进入 Promise.all().then(res) 中,无论成功失败,结果都在 res 里面。(问题:方式二,如果其中一个卡住了,就会一直处于等待状态)
Promise.race
Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
代码:
let fn = function(ps) {Promise.race(ps).then((result) => {console.log(result);}).catch((error) => {console.log(error);})};fn([p1, p2, p3, p4]); // --> ok2fn([p1, p2, p3]); // --> ok2fn([p1, p2]); // --> ok2fn([p3, p4]); // --> fail2fn([p1, p4]); // --> fail2fn([p1, p3]); // --> ok1
Promise.race() 结果是:无论成功与否,只要有一个返回,立马停止,将其作为结果。第一个执行结果,成功,then() ,失败,catch() 。
Promise.allSettled
Promise.allSettled()方法返回一个promise,该promise在所有给定的promise已被解析或被拒绝后解析,并且每个对象都描述每个promise的结果。
