map() function with async/await
The other answers have pretty well covered the details of how your examples behave, but I wanted to try to state it more succinctly.
const resultsPromises = myArray.map(async number => {
return await getResult(number);
});
const resultsPromises = myArray.map(number => {
return getResult(number);
});
Array.prototype.map
synchronously loops through an array and transforms each element to the return value of its callback.Both examples return a
Promise
.async
functions always return aPromise
.getResult
returns aPromise
.Therefore, if there are no errors you can think of them both in pseudocode as:
const resultsPromises = myArray.map(/* map each element to a Promise */);
As zero298 stated and alnitak demonstrated, this very quickly (synchronously) starts off each promise in order; however, since they're run in parallel each promise will resolve/reject as they see fit and will likely not settle (fulfill or reject) in order.
Either run the promises in parallel and collect the results with
Promise.all
or run them sequentially using a for * loop orArray.prototype.reduce
.
Alternatively, you could use a third-party module for chainable asynchronous JavaScript methods I maintain to clean things up and--perhaps--make the code match your intuition of how an async map operation might work:
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
const getResult = async n => {
await delay(Math.random() * 1000);
console.log(n);
return n;
};
(async () => {
console.log('parallel:');
await AsyncAF([1, 2, 3]).map(getResult).then(console.log);
console.log('sequential:');
await AsyncAF([1, 2, 3]).series.map(getResult).then(console.log)
})();
<script src="https://unpkg.com/[email protected]/index.js"></script>
Array.prototype.map()
is a function that transforms Arrays. It maps one Array to another Array. The most important part of its function signature is the callback. The callback is called on each item in the Array and what that callback returns is what is put into the new Array returned by map
.
It does not do anything special with what gets returned. It does not call .then()
on the items, it does not await
anything. It synchronously transforms data.
That means that if the callback returns a Promise
(which all async
functions do), all the promises will be "hot" and running in parallel.
In your example, if getResult()
returns a Promise
or is itself async, there isn't really a difference between your implementations. resultsPromises
will be populated by Promise
s that may or may not be resolved yet.
If you want to wait for everything to finish before moving on, you need to use Promise.all()
.
Additionally, if you only want 1 getResults()
to be running at a time, use a regular for
loop and await
within the loop.