如何等待来自 forEach 循环的多个异步调用?
Posted
技术标签:
【中文标题】如何等待来自 forEach 循环的多个异步调用?【英文标题】:How to wait for multiple asynchronous calls from forEach loop? 【发布时间】:2019-02-18 13:02:09 【问题描述】:尝试调用多个异步函数,导致结果为undefined
。
尝试async.waterfall
,但无法使其工作。
代码:
const pendingData = [];
async.waterfall([
function (callback)
WaitForApproval.find(, (err,result) =>
callback(null,result);
);
,
function (result, callback)
result.forEach(data =>
User.findOne(_id: data.uploadedBy, (err,name) =>
let total =
id: data._id,
name: name.name,
subject: data.subject,
uploadOn: data.uploadedAt
;
pendingData.push(total);
);
);
callback(null,'done');
], function (err,result)
if(result === 'done')
console.log(pendingData); // it is giving empty result.
);
如何等待异步函数?
【问题讨论】:
只需将result.forEach
更改为async.series
或async.parallel
How to wait for multiple asynchronous calls from for loop?的可能重复
【参考方案1】:
您遇到的问题是您是非异步 forEach 循环中的异步函数。
你有几个选择:
递归调用 mongoDB - 将此查询包装在一个函数中,该函数在查询返回后调用自身。
了解 mongoDB 批处理操作 - https://docs.mongodb.com/manual/reference/method/Bulk/
通过将异步瀑布中的回调函数声明为“异步”,然后在每个查询的函数内部使用“等待”,对每次调用使用异步/等待模式。开箱即用,forEach 不是异步的。如果您仍想使用 forEach,您可以异步重写它(见下文)或使用常规 for 循环:
async function asyncForEach(array, callback)
for (let index = 0; index < array.length; index++)
await callback(array[index], index, array)
** 除了此处发布的内容之外,还有其他方法可以解决此问题,但如果实施正确,这里有一些方法将起作用。
【讨论】:
这将在第一个User.findOne
完成后触发回调。那还为时过早。也许你可以测试pendingData
的长度:if (pendingData.length === result.length) callback(null, pendingData)
当我使用 forEach
时出现错误,callback
将在循环外使用。
@MarkMeyer 你是对的!我没有意识到这里有一个 forEach 被调用——我很抱歉;我很快对此做出了回应,因为我刚刚在工作中处理了同样的问题:)
@MarkMeyer,这个技巧奏效了。但肯定还有其他方法可以解决这个问题。【参考方案2】:
我建议您立即添加对callback(null,'done');
的调用pendingData.push(total);
你是对的,异步特性现在让你很难过,但假设你使用 Promise 并将它们链接在一起,那会为你省去很多麻烦。
有一次我遇到了类似的异步代码乱序问题,所以我使用自定义的 promise 函数(我猜到了)做了一点调整,并称之为 order..这样的想法可以解决你的问题,如果你可以正确地将其应用于您的代码 https://github.com/lalosh/Ideas/blob/master/promiseOrder.js
【讨论】:
你的 sn-p 很棒,但我认为有几件事可以改进它: - 删除控制台日志整数,它们是无关的 - 如果你使用 async/await 架构和 promisified 函数,你可以避免 .then() 回调以上是关于如何等待来自 forEach 循环的多个异步调用?的主要内容,如果未能解决你的问题,请参考以下文章
ForEach 循环中的异步/等待节点 Postgres 查询
如何正确调用 Parallel.ForEach 循环中的调用异步方法[重复]