В настоящее время у меня огромные проблемы при работе с асинхронной функцией. Первое, что я пытаюсь сравнить мой deleteArray (который содержит текущие данные, которые должны быть в коллекции) с данными в коллекции.
static async updateDocsInCollection(data) {
let deleteArray= [];
// Insert all data into array.
data.forEach(async (elem) => {
deleteArray.push(elem.serial);
}
MongoClient.connect('mongodb://' + config.database.host + ':' + config.database.port, { useNewUrlParser: true }, async function(err,db){
if (err) throw err;
// Get the current documents from "inventory" collection".
await dbo.collection("inventory").find({}).toArray(function(err, res) {
if (err) throw err;
// Iterate through res array and see if res element exists in
// deleteArray
res.forEach((elem) =>{
if(!deleteArray.includes(elem.serial)){
// if it don't, push it.
deleteArray.push(elem)
console.log(elem.serial + " Pushed into array");
}
});
});
// Iterate through deleteArray and delete it from collection.
deleteArray.forEach((elem) =>{
console.log(elem);
dbo.collection("onlineplayerservice").findOneAndDelete({ 'serial': elem.serial});
});
// closing db-connection.
db.close();
});
Проблема заключается в том, что код не выполняется в правильном порядке, потому что я не могу перебрать deleteArray, хотя я вижу (согласно console.log), что данные вводятся туда.
Есть ли у вас какие-либо советы о том, как я могу обеспечить синхронизацию этой функции?
Проблема в том, что вы используете async
функцию внутри вашего первого forEach(). Это означает, что вы выполняете итерацию своего массива с асинхронными функциями, возвращающими Promises, поэтому код не будет ждать завершения forEach перед переходом к следующему оператору.
Я не вижу никакой причины, по которой у вас здесь есть async
поэтому я бы просто удалил ее. Но если вам это действительно нужно, вот что вы должны сделать:
// Will wait for all lambda async function inside the forEach to finish
await Promise.all(data.forEach(async (elem) => {
deleteArray.push(elem.serial);
}));
В качестве подсказки, если все, что вам нужно, это получить атрибут serial
всех ваших элементов data
, вы должны использовать Arrays.map
следующим образом:
let deleteArray = data.map(function(elem) { return elem.serial; });
Другое дело, вы должны выбрать, использовать ли обратные вызовы или Promises с async/await, а не оба:
// Wrong
await dbo.collection("inventory").find({}).toArray(function(err, res) {});
// Good with promise and await
let res = await dbo.collection("inventory").find({}).toArray();
// Good with callback
dbo.collection("inventory").find({}).toArray(function(err, res) {});
static async updateDocsInCollection(data) {
// Insert all data into array.
let deleteArray = data.map(function(elem) { return elem.serial; });
const dbo = await MongoClient.connect('mongodb://' + config.database.host + ':' + config.database.port, { useNewUrlParser: true });
// Get the current documents from "inventory" collection".
const res = await dbo.collection("inventory").find({}).toArray();
// Iterate through res array and see if res element exists in deleteArray
res.forEach((elem) =>{
if(!deleteArray.includes(elem.serial)){
// if it don't, push it.
deleteArray.push(elem.serial) // You forgot the .serial here
console.log(elem.serial + " Pushed into array");
}
});
// Iterate through deleteArray and delete it from collection.
// The deleteArray already contains serials, not data elements
deleteArray.forEach((serial) =>{
console.log(serial);
dbo.collection("onlineplayerservice").findOneAndDelete({ 'serial': serial});
});
// closing db-connection.
db.close();
});