0

This my is code

  const listShift = await Shift.find().and([{ "shiftInstance.workers.worker": req.user }, { "shiftInstance.date": Date.parse(date) }]).select("name startTime endTime -_id target").populate("target target.checkPoints.checkPoint")

    //Find checkpoint
    listShift.forEach(async shift =>{
        listShift.target = await Target.findById(shift.target).populate("checkPoints.checkPoint")
        console.log(listShift);  //1

    })
    console.log(listShift);  //2

in 1 i have result of await Target ... but in 2 it disappear Can you explain it for me and tell me how to fix it?

Vincent
  • 1
  • 1
  • 2
  • 1
    `forEach` doesn't know about async functions. It just iterates over the elements in the array and calls the callback. Use a normal `for` loop. – Felix Kling Sep 10 '20 at 10:21
  • 2
    Does this answer your question? [Using async/await with a forEach loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) – Felix Kling Sep 10 '20 at 10:22

2 Answers2

0

forEach ignores the promise returned by the functrion passed to it as an argument. It will call the function for every element, which will run until it yields, returning a promise. forEach is thus simply incompatible with async functions.

yeoman
  • 1,671
  • 12
  • 15
0

forEach starts the async functions, then move on without waiting them to finish. Because of this the console.log(listShift); //2 part runs before any of the Target calls.

To wait for the async functions to finish, use a map with a Promise.all:

    await Promise.all(listShift.map(async shift =>{
        listShift.target = await Target.findById(shift.target).populate("checkPoints.checkPoint")
        console.log(listShift);  //1

    }));
    console.log(listShift);  //2
Tamás Sallai
  • 3,195
  • 1
  • 14
  • 25