map() with async vs promise.all()
如果我有一个元素数组并且我想对它们进行并行操作。
我会使用
我知道
在这里,它清楚地表明。
The Promise.all() method returns a single Promise that fulfills when all of the promises passed as an iterable have been fulfilled or when the iterable contains no promises or when the iterable contains promises that have been fulfilled and non-promises that have been returned. It rejects with the reason of the first promise that rejects, or with the error caught by the first argument if that argument has caught an error inside it using try/catch/throw blocks.
所以,是的,我们可以将简单的函数传递给
现在看看下面的代码。
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 | const promises = todayAssignedJobs.map(async todayAssigned => { const [leaderboard, created] = await Leaderboard.findOrCreate({...}); if (!created) { const rating = (todayAssigned.rating + leaderboard.rating * leaderboard.jobs_completed) / (leaderboard.jobs_completed + 1); const commission = todayAssigned.commission + leaderboard.commission; const jobsCompleted = leaderboard.jobs_completed + 1; await Leaderboard.update({ rating, commission, jobs_completed: jobsCompleted, updated_by: 'system', }, { where: { id: leaderboard.id, }, }); } await AssignedJob.update({ is_leaderboard_generated: true, }, { where: { id: todayAssigned.id, }, }); }); await Promise.all(promises); |
在这里,我有一个疑问。
我们正在迭代数组的每个元素并对它们进行异步操作。他们没有明确返回任何东西。
所以,我认为 map 也在这里做并行操作。
为什么要在这里使用
如果那是你想要的,并且你想收集所有返回的 Promise,以便以后可以看到它们何时都用
1 | Promise.all(someArray.map(callbackThatReturnsAPromiseHere)) |
而且,这是一种常见的设计模式。事实上,Bluebird Promise 库有一个特殊的函数将这两者结合起来,称为
听起来您正试图弄清楚是否应该只使用
仅供参考,
如果你想在所有操作完成后做某事,你只需要
1 2 3 4 5 6 7 8 | const promises = todayAssignedJobs.map(async todayAssigned => { // lots of async stuff }); await Promise.all(promises); // now, all Promises have resolved // alert the user that the leaderboard is completely updated |
如果您在确定所有 Promise 都已完成后不需要发生任何事情,那么
不过有一个问题 - 你没有处理错误,但应该处理错误,否则它们会给出警告或退出 Node 进程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | const processJob = async (todayAssigned) => { const [leaderboard, created] = await Leaderboard.findOrCreate({...}); if (!created) { // ... // ... todayAssignedJobs.forEach(async todayAssigned => { try { await processJob(todayAssigned); } catch(e) { // handle errors } }); |
这里
如果你在