Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
318 views
in Technique[技术] by (71.8m points)

javascript - map() function with async/await

There is quite some topics posted about how async/await behaves in javascript map function, but still, detail explanation in bellow two examples would be nice:

  const resultsPromises = myArray.map(async number => {
    return await getResult(number);
  });
  const resultsPromises = myArray.map(number => {
    return getResult(number);
  });

edited: this if of course a fictional case, so just opened for debate, why,how and when should map function wait for await keyword. solutions how to modify this example, calling Promise.all() is kind of not the aim of this question.
getResult is an async function

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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);
});
  1. Array.prototype.map synchronously loops through an array and transforms each element to the return value of its callback.

  2. Both examples return a Promise.

    • async functions always return a Promise.

    • getResult returns a Promise.

    • 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 */);
  1. 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.

  2. Either run the promises in parallel and collect the results with Promise.all or run them sequentially using a for * loop or Array.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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...