After reviewing other discussions on this platform, it seems that the general agreement is that forEach should be synchronous and block.
However, in my code, something appears to be off as it doesn't behave that way:
var noDupes = false; // set to true eventually but currently blocking any inserts
console.log('forEach');
courses.forEach((course) =>
{
const promiseNoDupe = new Promise((resolve, reject) =>
{
dbo.collection("courses").findOne({ id: course.id }, (err, result) =>
{
if (err) throw err;
if (result) { console.log('dupe'); return reject('dupe'); }
console.log('nodupe');
resolve('nodupe');
});
});
noDupes &= promiseNoDupe.then(() =>
{
console.log('true promise');
return true;
}).catch(() =>
{
console.log('false promise');
return false;
});
});
console.log('End forEach');
if (noDupes)
{
console.log('Inserting many');
dbo.collection("courses").insertMany(courses, (err, result) =>
{
if (err) return res.status(400).send(error.details[0].message);
res.send(courses);
});
}
else
{
console.log('No Dupes allowed');
res.status(400).send('Inserting duplicate ID not Allowed!');
}
Console output:
forEach
End forEach
No Dupes allowed
nodupe
true promise
nodupe
true promise
The "End forEach" section runs before the promise is fulfilled and before any internal processing takes place! Consequently, the logic dependent on the promise is being executed prematurely.
I'm uncertain about what's causing this issue, but I am attempting to ensure that all checks within the forEach loop are completed before inserting any new records.