Reputation: 327
I've been trying to fix this for the last days with no success. I'm pretty new to node and async/sync concept and obviously I'm missing something.
I need to run a loop one after each the other (async) inside an event. This loop interacts with database and takes some time to be completed. I've done my best with event emitter and setImmediate(), but still get processMessage and storeMessage functions fired sync. Please take a look:
const EventEmitter = require('events')
const emitter = new EventEmitter()
msg.once('body', stream => {
emitter.on('done',() => {
try {
setImmediate(async ()=>{ // <-- Here I'm trying to queue async the funtion
await emailService.processMessage(stream);
})
} catch(err) {
helper.logger.error('Problem stockpiling mails to be processed');
}
});
});
Then I call this when msg has finished
f.once('end', function() {
emitter.emit('done');
});
I don't know if the problem is inside the function I'm calling in setImmediate so I'll leave them below.
exports.processMessage = async (stream) => {
/// ...
await storeMessage(parsed);
/// ...
}
async function storeMessage (parsed){
// Some async database interaction
}
Upvotes: 1
Views: 111
Reputation: 138257
Async functions run until they reach an await
, then they halt and other functions can run. Thus, if you call an async function twice, it will run "in parallel":
async function task(id) {
console.log("before " + id);
await undefined;
console.log("after " + id);
}
task(1);
task(2);
Now the usual solution would be to await
the different tasks in one async function, so that they run after each other:
await task(1);
await task(2);
Unfortunately, in your case, emitter.on('done',() => {
might trigger multiple times, also while a task is running², so working with it won't be that easy. So we have to use promises to chain async functions across multiple callbacks:
let done = Promise.resolve();
emitter.on('done',() => {
done = done.then(async function() {
// ...
});
});
² as far as I can see. There might be more elegant solutions for your usecase though.
Upvotes: 2