Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

await with array foreach containing async await

In node.js I need to use a function procesMultipleCandidates () which contains Array.foreach which process insert every element into db. but the entire function should return response after completing all insertion operation

JavaScript Code

async function procesMultipleCandidates (data) {
  let generatedResponse = []
  await data.forEach(async (elem) => {
    try {    
          
           // here candidate data is inserted into  
           let insertResponse = await insertionInCandidate(elem) 
           //and response need to be added into final response array 
           generatedResponse.push(insertResponse)
    } catch (error) {
    console.log('error'+ error);
    }
  })
  console.log('complete all') // gets loged first
  return generatedResponse // return without waiting for process of 
}

And as described above last return statement not waiting for the foreach execution to complete first.

like image 254
Irony Stack Avatar asked Aug 08 '18 04:08

Irony Stack


People also ask

Can you use async await in forEach?

forEach is not designed for asynchronous code. (It was not suitable for promises, and it is not suitable for async-await.)

Why async await not working in forEach?

The Solution It turns out that the array. forEach method only accepts a synchronous function, and therefore is NOT compatible with the async/await syntax. Instead, you can use the for … of iterator as per below which is compatible with the async/await syntax.

Is forEach async or sync?

forEach() expects a synchronous function — it does not wait for promises. Make sure you are aware of the implications while using promises (or async functions) as forEach callbacks.

What happens if you use await inside a loop and what are the alternatives?

When evaluate for loop, we have await promise inside the async function, the execution will pause until the await promise is settled. So, you can think of that the files are read one by one in a determined order. Sometimes, we really need the the async functions to be executed in a sequential order.


1 Answers

Use Array.prototype.map and Promise.all:

async function procesMultipleCandidates (data) {
  let generatedResponse = []
  await Promise.all(data.map(async (elem) => {
    try {
      // here candidate data is inserted into  
      let insertResponse = await insertionInCandidate(elem)  
      // and response need to be added into final response array 
      generatedResponse.push(insertResponse)
    } catch (error) {
      console.log('error'+ error);
    }
  }))
  console.log('complete all') // gets loged first
  return generatedResponse // return without waiting for process of 
}

Or use a for/of loop if you don't want the loop run concurrently:

async function procesMultipleCandidates (data) {
  let generatedResponse = []
  for(let elem of data) {
    try {
      // here candidate data is inserted into  
      let insertResponse = await insertionInCandidate(elem)  
      // and response need to be added into final response array 
      generatedResponse.push(insertResponse)
    } catch (error) {
      console.log('error'+ error);
    }
  }
  console.log('complete all') // gets loged first
  return generatedResponse // return without waiting for process of 
}
like image 99
SimpleJ Avatar answered Sep 29 '22 17:09

SimpleJ