Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async/Await inside Array#map()

I'm getting compile time error with this code:

const someFunction = async (myArray) => {     return myArray.map(myValue => {         return {             id: "my_id",             myValue: await service.getByValue(myValue);         }     }); }; 

Error message is:

await is a reserved word

Why can't I use it like this?

I also tried another way, but it gives me same error:

 const someFunction = async (myArray) => {     return myArray.map(myValue => {         const myNewValue = await service.getByValue(myValue);         return {             id: "my_id",             myValue: myNewValue          }     }); }; 
like image 574
WelcomeTo Avatar asked Feb 27 '17 15:02

WelcomeTo


People also ask

How do you use async-await in array map?

So, the solution is to use Promise. all() function in javascript. We need to wrap the array inside the Promise. all(array) function which will then wait for all the promises to get resolved and return the result to the user.

Is array map async?

The . map() algorithm applies an async callback to each element of an array, creating promises as it does. However, the returned result by . map() is no promise, but an array of promises.

Can we use async in map function?

You would have to implement either callbacks or promises in the function you are using inside map. Probably a good introduction in using of async functions inside Array. map was suggested by Tamás Sallai. As a result use Promise.


2 Answers

You can't do this as you imagine, because you can't use await if it is not directly inside an async function.

The sensible thing to do here would be to make the function passed to map asynchronous. This means that map would return an array of promises. We can then use Promise.all to get the result when all the promises return. As Promise.all itself returns a promise, the outer function does not need to be async.

const someFunction = (myArray) => {     const promises = myArray.map(async (myValue) => {         return {             id: "my_id",             myValue: await service.getByValue(myValue)         }     });     return Promise.all(promises); } 
like image 126
lonesomeday Avatar answered Sep 22 '22 03:09

lonesomeday


If you want to run map with an asynchronous mapping function you can use the following code:

const resultArray = await Promise.all(inputArray.map(async (i) => someAsyncFunction(i))); 

How it works:

  • inputArray.map(async ...) returns an array of promises - one for each value in inputArray.
  • Putting Promise.all() around the array of promises converts it into a single promise.
  • The single promise from Promise.all() returns an array of values - the individual promises each resolve to one value.
  • We put await in front of Promise.all() so that we wait for the combined promise to resolve and store the array of resolved sub-promises into the variable resultArray.

In the end we get one output value in resultArray for each item in inputArray, mapped through the function someAsyncFunction. We have to wait for all async functions to resolve before the result is available.

like image 39
MattCochrane Avatar answered Sep 20 '22 03:09

MattCochrane