I am creating a module that is executing tasks based on a config it receives. These tasks are asynchronous and are returning a promise. Currently there are only two tasks to handle, but if there are more coming up, I will run into a problem of identifying which result of Promise.all()
belongs to which task.
Here is a snap of my current code:
let asyncTasks = [];
let result = {};
if (config.task0) {
asyncTasks.push(task0(param));
}
if (config.task1) {
asyncTasks.push(task1(param));
}
Promise.all(asyncTasks)
.then(results => {
// TODO: There has to be a prettier way to do this..
if (config.task0) {
result.task0 = results[0];
result.task1 = config.task1 ? results[1] : {};
} else if (config.task1) {
result.task0 = {};
result.task1 = results[0];
} else {
result.task0 = {};
result.task1 = {};
}
this.sendResult(result)
});
The config looks like this:
const config = {
task0: true,
task1: true
};
As mentioned in the code, there has to be a prettier and more scaleable way to identify which result is coming from which task, but I can't find anything regarding Promise.all()
that could help with this.
How do I identify which value belongs to which promise if Promise.all()
resolves?
all() The Promise. all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will fulfill when all of the input's promises have fulfilled, or if the input iterable contains no promises.
Yes, the values in results are in the same order as the promises .
all() Method: Fulfillment: The returned promise is fulfilled, If the passed iterable is empty, then this method returns an promise synchronously which is already resolved. If all of the passed promises are fulfill, the returned Promises are fulfilled asynchronously.
Promise.all
resolves with an array of values, where each value's index in the array is the same as the index of the Promise in the original array passed to Promise.all
that generated that value.
If you need anything more fancy you'll need to keep track of it yourself or use another library that offers such functionality (like Bluebird).
There's really no need to use anything other than Promise.all
. You're experiencing difficulty because the other structure of your program (config
, and arbitrary link of config key to function) is pretty messy. You might want to consider restructuring the code altogether
const config = {
task0: true,
task1: true,
task2: false
}
// tasks share same keys as config variables
const tasks = {
task0: function(...) { ... },
task1: function(...) { ... },
task2: function(...) { ... }
}
// tasks to run per config specification
let asyncTasks = Object.keys(config).map(prop =>
config[prop] ? tasks[prop] : Promise.resolve(null))
// normal Promise.all call
// map/reduce results to a single object
Promise.all(asyncTasks)
.then(results => {
return Object.keys(config).reduce((acc, task, i) => {
if (config[task])
return Object.assign(acc, { [prop]: results[i] })
else
return Object.assign(acc, { [prop]: {} })
}, {})
})
// => Promise({
// task0: <task0 result>,
// task1: <task1 result>,
// task2: {}
// })
Note: we can depend on the order of results
because we used Object.keys(config)
to create the input array of promises and Object.keys(config)
again to create the output object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With