Promise 并发(JS) 在 async 函数中,“过度 await”代码非常普遍。将 Promise.all() 与异步函数一起使用,可以有效的实现并发。
例如,两个异步函数 fetchA, fetchB:
1 2 3 4 5 6 7 8 9 async function fetchA ( ) { const response = await fetch ("/path/a" ); return await response.json (); } async function fetchB ( ) { const response = await fetch ("/path/b" ); return await response.json (); }
await 运算符会让异步函数串行执行,执行 fetchA()获得结果之后,才去执行 fetchB()。如下:
1 2 3 4 5 async function awaitFunc ( ) { const a = await fetchA (); const b = await fetchB (); return handleResult (a, b); }
我们可以使用 Promise.all 让异步函数并发执行。
1 2 3 4 async function promiseAllFunc ( ) { const [a, b] = await Promise .all ([fetchA (), fetchB ()]); return handleResult (a, b); }
Promise 类提供了以下四种异步任务的并发。
Ox01 Promise.all() Promise.all() 静态方法接受一个 Promise 可迭代对象作为输入,并返回一个 Promise。当所有输入的 Promise 都被兑现时,返回的 Promise 也将被兑现(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。
所有的 Promise 都被兑现时兑现,并返回一个包含所有兑现值的数组;
在任何一个输入的 Promise 被拒绝时立即拒绝,并带回被拒绝的原因;
1 2 3 4 5 6 7 8 9 10 const promise1 = Promise .resolve (3 );const promise2 = 42 ;const promise3 = new Promise ((resolve, reject ) => { setTimeout (resolve, 100 , "foo" ); }); Promise .all ([promise1, promise2, promise3]).then ((values ) => { console .log (values); });
Ox02 Promise.allSettled() Promise.allSettled() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个单独的 Promise。当所有输入的 Promise 都已敲定时(包括传入空的可迭代对象时),返回的 Promise 将被兑现,并带有描述每个 Promise 结果的对象数组。
在所有的 Promise 都被敲定时兑现,返回一个带有描述每个 Promise 结果的对象数组;
永远不会被 reject;
1 2 3 4 5 6 7 8 9 10 11 12 13 Promise .allSettled ([ Promise .resolve (33 ), new Promise ((resolve ) => setTimeout (() => resolve (66 ), 0 )), 99 , Promise .reject (new Error ("一个错误" )), ]).then ((values ) => console .log (values));
status: 一个字符串,要么是 “fulfilled”,要么是 “rejected”,表示 promise 的最终状态。
value: 仅当 status 为 “fulfilled”,才存在。promise 兑现的值。
reason: 仅当 status 为 “rejected”,才存在,promsie 拒绝的原因。
Ox03 Promise.any() 在任意一个 Promise 被兑现时兑现;仅在所有的 Promise 都被拒绝时才会拒绝。
1 2 3 4 5 6 7 8 9 const promise1 = Promise .reject (0 );const promise2 = new Promise ((resolve ) => setTimeout (resolve, 100 , "quick" ));const promise3 = new Promise ((resolve ) => setTimeout (resolve, 500 , "slow" ));const promises = [promise1, promise2, promise3];Promise .any (promises).then ((value ) => console .log (value));
Ox04 Promise.race() 在任意一个 Promise 被敲定时敲定。换句话说,在任意一个 Promise 被兑现时兑现;在任意一个的 Promise 被拒绝时拒绝。
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 function sleep (time, value, state ) { return new Promise ((resolve, reject ) => { setTimeout (() => { if (state === "兑现" ) { return resolve (value); } else { return reject (new Error (value)); } }, time); }); } const p1 = sleep (500 , "一" , "兑现" );const p2 = sleep (100 , "二" , "兑现" );Promise .race ([p1, p2]).then ((value ) => { console .log (value); }); const p3 = sleep (100 , "三" , "兑现" );const p4 = sleep (500 , "四" , "拒绝" );Promise .race ([p3, p4]).then ( (value ) => { console .log (value); }, (error ) => { } ); const p5 = sleep (500 , "五" , "兑现" );const p6 = sleep (100 , "六" , "拒绝" );Promise .race ([p5, p6]).then ( (value ) => { }, (error ) => { console .error (error.message ); } );
参考 MDN Web 开发技术:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise