原文:The Promise.all()
Function in JavaScript
Promise.all()
函数可以并行执行多个Promise,然后收集执行结果。
Promise.all()
函数可以把一个Promise数组转换成单个Promise,当原数组中所有Promise变为fulfilled,它才变为fulfilled。
以下例子使用Promise.all()
包住一个Promise数组:
1 2 3 4 5 6 7 8 9 10 11 12 13
| const p1 = Promise.resolve(1);
const p2 = new Promise(resolve => setTimeout(() => resolve(2), 100));
const pAll = Promise.all([p1, p2]); pAll instanceof Promise;
const arr = await pAll;
Array.isArray(arr); arr[0]; arr[1];
|
异步函数的并行执行
当使用异步函数时,Promise.all()
可以并行的执行代码。将异步函数调用的数组传入Promise.all()
,JavaScript会并行的执行异步函数。
假设有两个异步函数getName()
和getAge()
,以下展示了如何用Promise.all()
并行的执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| async function getName() { await new Promise(resolve => setTimeout(resolve, 200));
return 'Jean-Luc Picard'; }
async function getAge() { await new Promise(resolve => setTimeout(resolve, 200));
return 59; }
const start = Date.now(); const [name, age] = await Promise.all([getName(), getAge()]); const end = Date.now();
name; age;
end - start;
|
错误处理
如果其中一个Promise变为rejected,Promise.all()
立刻变为rejected,抛出相同的错误。
1 2 3 4 5 6 7 8 9 10
| const success = new Promise(resolve => setTimeout(() => resolve('OK'), 100)); const fail = new Promise((resolve, reject) => { setTimeout(() => reject(new Error('Oops')), 100); });
try { await Promise.all([success, fail]); } catch (err) { err.message; }
|
注意,Promise是无法取消的,即使其中一个抛出错误,其他每个Promise仍然会继续执行。如果Promise.all()
执行一个异步函数数组,其中一个异步函数抛出错误,Promise.all()
会立即变为rejected,并返回错误。但其他的函数会继续执行下去。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| let finished = false;
const success = async function() { await new Promise(resolve => setTimeout(resolve, 100));
finished = true; return 'OK'; } const fail = async function() { await new Promise(resolve => setTimeout(resolve, 10)); throw new Error('Oops'); } try { await Promise.all([success(), fail()]); } catch (err) { err.message;
finished;
await new Promise(resolve => setTimeout(resolve, 100)); finished; }
|
Promise.all()
函数不止可以用数组,参数可以是任何可迭代对象。数组是可迭代的,Generator函数也是可迭代的。也就是说可以传递一个yields Promise的Generator,Promise.all()
会把所有yields出来的Promise包装成单个的Promise。
1 2 3 4 5 6 7 8 9
| const generatorFn = function*() { for (let i = 1; i <= 5; ++i) { yield Promise.resolve(i); } }
const arr = await Promise.all(generatorFn());
arr;
|
async/await是JavaScript中并发的未来趋势。“Mastering Async/Await”教你如何在几个小时内,用async/await构建前后端APP,来看看吧!