0

When we run the following code, it wait's for 5 seconds and produces three lines as result, as per my understanding of async await it should show single line every 5 seconds thus ending in 15 seconds. Can some one please help me what I am not doing correctly. the node.js code is as below :

const records = [
  { "REFNO": 466999, "VEHICLE": "Toyota Yaris 1.5", "MODELYEAR": 2018 },
  { "REFNO": 477555, "VEHICLE": "Nissan Altima 3.0", "MODELYEAR": 2020 },
  { "REFNO": 467000, "VEHICLE": "Honda Civic 2.0", "MODELYEAR": 2019 }
]

records.forEach(async (record) => {
  let vehicleName = await fnGetVehicleName(record);
  console.log(`Reference No. : ${record.REFNO} is a ${vehicleName}`);
});

function fnGetVehicleName(xvehicle) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(xvehicle.VEHICLE);
    }, 5 * 1000)
  })
}
  • 1
    `.forEach()` is not promise-aware so that loop does not pause for `await`. Use a regular `for` loop if you want the loop to pause for your `await`. – jfriend00 Jan 18 '20 at 17:32
  • 1
    `forEach` will not await the function it is given, and ignore the return. It will simply call the async function for every array element. All these calls will wait the five seconds, until the promise is resolved, but not sequentially. Pretty sure there is a dupe for this... – ASDFGerte Jan 18 '20 at 17:32
  • 1
    Does this answer your question? [Using async/await with a forEach loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) – ASDFGerte Jan 18 '20 at 17:34
  • Yes, answer is spot-on :) thanks for your reply. – M. Khalid Umer Jan 19 '20 at 09:30

1 Answers1

0

.forEach() is using callback, on each iteration .forEach() will call the callback function and continue with the next iteration.

You can try with a recursive function for this particular use-case.

const records = [
  { REFNO: 466999, VEHICLE: "Toyota Yaris 1.5", MODELYEAR: 2018 },
  { REFNO: 477555, VEHICLE: "Nissan Altima 3.0", MODELYEAR: 2020 },
  { REFNO: 467000, VEHICLE: "Honda Civic 2.0", MODELYEAR: 2019 }
];

function fnGetVehicleName(xvehicle) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(xvehicle.VEHICLE);
    }, 5 * 1000);
  });
}

let count = 0;
function loop() {
  if (count >= records.length) return;
  (async function() {
    let vehicleName = await fnGetVehicleName(records[count]);
    console.log(`Reference No. : ${records[count].REFNO} is a ${vehicleName}`);
    count++;
    loop();
  })();
}

loop();

If you want to do this with loop then you have to add the loop inside the async function.

Example

const records = [
  { REFNO: 466999, VEHICLE: "Toyota Yaris 1.5", MODELYEAR: 2018 },
  { REFNO: 477555, VEHICLE: "Nissan Altima 3.0", MODELYEAR: 2020 },
  { REFNO: 467000, VEHICLE: "Honda Civic 2.0", MODELYEAR: 2019 }
];

async function exec() {
  for (const record of records) {
    let vehicleName = await fnGetVehicleName(record);
    console.log(`Reference No. : ${record.REFNO} is a ${vehicleName}`);
  }
}

function fnGetVehicleName(xvehicle) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(xvehicle.VEHICLE);
    }, 5 * 1000);
  });
}


exec();
Sohail Ashraf
  • 10,078
  • 2
  • 26
  • 42