I have an array of resolved Promises:
[Promise, Promise, Promise, ...]
Each of these promises when resolved returns a value. How do I create a function that returns the map of this array of promises to the value that each promise resolves to?
[value_1, value_2, value_3, ...]
Here's the closest I've gotten so far:
const mapPromisesToValues = promises => {
Promise.all(promises, values => {
// how do I return these values from mapPromisesToValues
return values
});
}
To be more specific, the reason why I ask is because I have a collection of arrays of Promises.
const collection_1 = [Promise, Promise, Promise, ...];
const collection_2 = [Promise, Promise, Promise, ...];
//...
and I want to batch these collection of promises mapped into a collection of values into 1 object, that I will then pass into another function that will be called once - in this case React's setState
:
this.setState({
...this.state,
values_1,
values_2,
//...
});
I have an array of resolved Promise ... how do I return these values from mapPromisesToValues
Even though you know the promises are resolved, you can't return a map of their values from your function. The only way to get the value of a promise is via a then
callback, and that callback is guaranteed to be called asynchronously, which means that your function cannot return the value; it can only return a promise of the value (e.g., as Promise.all
does).
You'll have to just have your function return the Promise.all
and have the consumer of the function use it.
Re your edit:
To be more specific, the reason why I ask is because I have a collection of arrays of Promises.
const collection_1 = [Promise, Promise, Promise, ...]; const collection_2 = [Promise, Promise, Promise, ...];
//...
and I want to batch these collection of promises mapped into a collection of values into 1 object, that I will then pass into another function that will be called once - in this case React's
setState
:this.setState({ ...this.state, values_1, values_2, //... });
That's fine, you don't need to do that synchronously. Simply:
Promise.all([
Promise.all(collection_1),
Promise.all(collection_2),
// etc.
])
.then(([values_1, values_2, /*etc*/]) => {
this.setState({values_1, values_2,/*etc*/});
});
Note that I left off ...this.state
there. Two reasons:
If you're setting state based on existing state, you must use the callback version of setState
, not the one accepting an object; and
State updates can be partial, so ...this.state
is unnecessary extra work.
Depending on your coding environment, you may find it useful to adopt async
/await
(for instance, if you're transpiling, or you're doing this on Node.js can can use an up-to-date copy of Node.js). async
/await
lets you write your code according to its logical flow, rather than its synchronous flow. Within an async
function, you use await
to suspend the function and wait for a promise to resolve. async
functions are syntactic sugar for functions that return promises, and await
is syntactic sugar for consuming promises (e.g., then
and catch
).
To make the transition from synchronous-flow to logical-flow, you make your entry point an async
function that you handle errors from:
(async () => {
// Your logical flow code here
}).catch(error => {
// Handle the error
});
Then, your function could be an async
function:
async function example() {
// ...
return await Promise.all(thePromises)
}
...which any other async
function can use via await
:
let values = await example();
You can't get the values from the promises synchronously by the nature of promises, sadly. You have to do this:
const mapPromisesToValues = promises => {
return Promise.all(promises);
}
mapPromisesToValues(promises).then(values => console.log(values));
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