Reputation: 27
Trying to make call to multiple asynchronous function, and due to which getting result as undefined
.
Tried async.waterfall
, however not able to make it work.
Code:
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.
}
});
How to wait for asynchronous function?
Upvotes: 1
Views: 2260
Reputation: 515
The issue you are having is that you are async functions within a non-async forEach loop.
You have a few options here:
Make the mongoDB call recursively - wrap this query in a function that calls itself after the query returns.
Read about mongoDB batch operations - https://docs.mongodb.com/manual/reference/method/Bulk/
Use an async/await pattern with each call by declaring the callback function within the async waterfall as 'async' and then using 'await' inside of the function for each query. Out of the box, forEach is not async. If you want to still use forEach, you can either re-write it async (See below) or use a regular for loop:
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array)
}
}
** There are additional ways to solve this beyond what is posted here, but here's a few things that will work if implemented correctly.
Upvotes: 2
Reputation: 3415
I would suggest you add the call for callback(null,'done');
immediately pendingData.push(total);
you are right, the async nature is making things hard for you now, but suppose you used Promises and chain them together, that would save you a lot of trouble.
once a time I had a similar problem of asynchronous code running out of order I wanted so I made a little Tweak using a custom promise function(I mead up) and call it order..such Idea can solve your problem if you could apply it to your code properly https://github.com/lalosh/Ideas/blob/master/promiseOrder.js
Upvotes: 2