Reputation: 5875
In my code I have conditional tasks, which all return a promise. I need the tasks to run in sequence.
My current implementation looks something like this:
var chain = [];
if (/* some condition for task A */) {
chain.push(function(doContinue){
taskA().then(doContinue);
});
}
if (/* some condition for task B */) {
chain.push(function(doContinue){
taskB().then(doContinue);
});
}
if (/* some condition for task C */) {
chain.push(function(doContinue){
taskC().then(doContinue);
});
}
var processChain = function () {
if (chain.length) {
chain.shift()(processChain);
} else {
console.log("all tasks done");
}
};
processChain();
This works fine, but initially I was looking for a way to create the chain using only Promises and chaining all functions using .then
, but I wasn't able to get a working solution.
If there's a cleaner way using only Promises and chains of then
calls, then I'd love to see an example.
Upvotes: 25
Views: 17485
Reputation: 106375
One possible approach:
var promiseChain = Promise.resolve();
if (shouldAddA) promiseChain = promiseChain.then(taskA);
if (shouldAddB) promiseChain = promiseChain.then(taskB);
if (shouldAddC) promiseChain = promiseChain.then(taskC);
return promiseChain;
Another one:
return Promise.resolve()
.then(shouldAddA && taskA)
.then(shouldAddB && taskB)
.then(shouldAddC && taskC);
Upvotes: 32
Reputation: 135197
You can use the new async
/await
syntax
async function foo () {
let a = await taskA()
if (a > 5) return a // some condition, value
let b = await taskB()
if (b === 0) return [a,b] // some condition, value
let c = await taskC()
if (c < 0) return "c is negative" // some condition, value
return "otherwise this"
}
foo().then(result => console.log(result))
What's nice about this is – aside from the code being very flat and readable (imo) – values a
, b
, and c
are all available in the same scope. This means your conditions and return values can depend on any combination of your tasks' promised values.
Upvotes: 5