How can I execute array of promises in sequential order?
If you already have them in an array then they are already executing. If you have a promise then it's already executing. This is not a concern of promises (I.E they are not like C# Task
s in that regard with .Start()
method). .all
doesn't execute anything
it just returns a promise.
If you have an array of promise returning functions:
var tasks = [fn1, fn2, fn3...];
tasks.reduce(function(cur, next) {
return cur.then(next);
}, RSVP.resolve()).then(function() {
//all executed
});
Or values:
var idsToDelete = [1,2,3];
idsToDelete.reduce(function(cur, next) {
return cur.then(function() {
return http.post("/delete.php?id=" + next);
});
}, RSVP.resolve()).then(function() {
//all executed
});
Yet another approach is to define a global sequence function on the Promise
prototype.
Promise.prototype.sequence = async (promiseFns) => {
for (let promiseFn of promiseFns) {
await promiseFn();
}
}
Then you can use it anywhere, just like Promise.all()
Example
const timeout = async ms => new Promise(resolve =>
setTimeout(() => {
console.log("done", ms);
resolve();
}, ms)
);
// Executed one after the other
await Promise.sequence([() => timeout(1000), () => timeout(500)]);
// done: 1000
// done: 500
// Executed in parallel
await Promise.all([timeout(1000), timeout(500)]);
// done: 500
// done: 1000
Disclaimer: Be careful editing Prototypes!
ES7 way in 2017.
<script>
var funcs = [
_ => new Promise(resolve => setTimeout(_ => resolve("1"), 1000)),
_ => new Promise(resolve => setTimeout(_ => resolve("2"), 1000)),
_ => new Promise(resolve => setTimeout(_ => resolve("3"), 1000)),
_ => new Promise(resolve => setTimeout(_ => resolve("4"), 1000)),
_ => new Promise(resolve => setTimeout(_ => resolve("5"), 1000)),
_ => new Promise(resolve => setTimeout(_ => resolve("6"), 1000)),
_ => new Promise(resolve => setTimeout(_ => resolve("7"), 1000))
];
async function runPromisesInSequence(promises) {
for (let promise of promises) {
console.log(await promise());
}
}
</script>
<button onClick="runPromisesInSequence(funcs)">Do the thing</button>
This will execute the given functions sequentially(one by one), not in parallel. The parameter promises
is an array of functions, which return Promise
.
Plunker example with the above code: http://plnkr.co/edit/UP0rhD?p=preview
With ECMAScript 2017 async functions it would be done like this:
async function executeSequentially() {
const tasks = [fn1, fn2, fn3]
for (const fn of tasks) {
await fn();
}
}
You can use BabelJS to use async functions now