Reputation: 12718
I am trying to syncronously run an array of async functions using eachSeries from async
library.
According to this SO Post, they say
The difference with async.eachSeries is that each iteration will wait for the async operation to complete before starting the next one.
This is what I want.
Question: I'm not quite understanding how to use eachSeries
to call the next async
setTimeout
only after the returning internal promise next()
resolves.
I push two async setTimeout
functions into my queue:
this.dialogTimerQueue.push(this.getNextDialogTimer(data, 1000));
this.dialogTimerQueue.push(this.getNextDialogTimer(data2, 1000));
console.log(this.dialogTimerQueue); // [101, 102]
Then attempt to iterate through:
// https://caolan.github.io/async/docs.html#eachSeries
async.eachSeries(this.dialogTimerQueue, (result) => {
});
The problem is, both setTimeout
s run in parallel. They need to run one after another.
getNextDialogTimer
returns a new setTimeout
which itself returns a Promise next()
getNextDialogTimer: function(dialog, ms) {
let foo = setTimeout(() => {
// only when next() completes, call next in async series
return this.next(dialog);
}, this.npcDialogDelay * ms);
console.log('Timeout: ', foo); // 101 or 102
return foo;
},
next()
promise:
// Return promise
next: function(dialog) {
var promiseTest = this.screenObj.conversation().addDialogToCenterScreen('npc', dialog, '');
console.log('Next: ', promiseTest);
return promiseTest;
},
Console.log shows as:
async.eachSeries(this.dialogTimerQueue, ({dialog, ms}, cb) => {
setTimeout(() => {
console.log('RESOLVING ' + dialog);
this.next(dialog).then(() => {
cb();
});
}, this.npcDialogDelay * ms);
});
Upvotes: 2
Views: 110
Reputation: 370819
The problem is that when you call getNextDialogTimer
, you start / set the timeout
immediately - that's the first line of the function. They start as soon as they're added to the queue, which is not what you want.
You could queue a callable function instead, which will start the timeout when called. Or, you could just queue the dialog, ms
items, which will probably be easier to understand, eg:
const dialogTimerQueue = [];
const data = 'foo';
const data2 = 'bar';
const npcDialogDelay = 1;
const next = () => new Promise(resolve =>
setTimeout(() => {
console.log('next resolved');
resolve();
}, 500)
);
dialogTimerQueue.push({ dialog: data, ms: 1000 });
dialogTimerQueue.push({ dialog: data2, ms: 1000 });
async.eachSeries(dialogTimerQueue, ({ dialog, ms }, cb) => {
setTimeout(() => {
console.log('resolving ' + dialog);
next().then(cb);
}, npcDialogDelay * ms);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/async/2.6.1/async.min.js"></script>
Upvotes: 1