guidsen
guidsen

Reputation: 2393

Add delay between array of promises

I'm having troubles by adding a delay between executing a Promise. I want them to execute in a specific sequence. I've tried Promise.mapSeries without success.

My working code currently looks like:

await Promise.delay(1000);
await accept(user.id, admin.id);
await Promise.delay(1000);
await accept(user.id, employee.id);
await Promise.delay(1000);
await reject(user.id, employee.id);

I've tried this with Promise.mapSeries without success:

const promises = [
  accept(user.id, admin.id),
  accept(user.id, employee.id),
  reject(user.id, employee.id)
];

await Promise.mapSeries(promises, () => Promise.delay(1000));

Upvotes: 1

Views: 1071

Answers (2)

Bergi
Bergi

Reputation: 664385

mapSeries doesn't help when you already have an array of promises. Constructing the array and creating the promises already starts the actions, which will run in parallel not in sequence.

The simplest solution would be a simple loop:

const actions = [
    { action: accept, target: user, source: admin },
    { action: accept, target: user, source: employee },
    { action: reject, target: user, source: employee }
]
for (const a of actions) {
    await Promise.delay(1000);
    await a.action(a.target.id, a.source.id);
}

but you can also use mapSeries instead of that:

await Promise.mapSeries(actions, a =>
    Promise.delay(1000)
    .then(() => a.action(a.target.id, a.source.id))
);

If your actions are more heterogenous, just make them functions:

const actions = [
    () => accept(user.id, admin.id),
    () => accept(user.id, employee.id),
    () => reject(user.id, employee.id)
];
for (const f of actions) {
    await Promise.delay(1000);
    await f()
}
await Promise.mapSeries(actions, async f => {
    await Promise.delay(1000);
    return f();
});

Upvotes: 5

CodingIntrigue
CodingIntrigue

Reputation: 78525

If you want to run the Promises in sequence, you need to delay their execution. You can do this by making your array return a function which then returns a Promise and passing that to mapSeries:

const arr = [
    () => Promise.resolve(1) /* () => accept(user.id, admin.id) */,
    () => Promise.resolve(2) /* () => accept(user.id, employee.id) */,
    () => Promise.resolve(3) /* () => reject(user.id, employee.id) */
];
// Now use mapSeries to execute the promises in sequence
Promise.mapSeries(arr, item => {
	return Promise.delay(1000).then(item);
})
.then(arr => console.log(arr));
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.4.1/bluebird.js"></script>

Upvotes: 3

Related Questions