Вы можете использовать Async/await
, чтобы сделать код более читабельным, и использовать for of
для итерации по данным.
for of
l oop будет ожидать завершения первой итерации, а затем go для второго и так далее.
С другой стороны, forEach основан на обратном вызове, поэтому он будет выполнять и регистрировать обратный вызов для каждой итерации в очереди обратных вызовов и выходить из него, не дожидаясь завершения обратных вызовов.
Попробуйте это
async refreshDevices(_timespan) {
const status = {
added: 0,
updated: 0,
};
// Standard API fetch & json() conversion
try {
let response = await fetch(`https://api.example.com/test×pan=${timespan}`)
let data= await response.json();
for (const device of data) {
try {
let record = await findDevice(device._id);
if (!record) {
addDeviceRecord(device);
status.added++;
} else {
deviceSeen(device._id);
status.updated++;
}
} catch (error) {
console.log('Error!');
}
}
systemlog.log({
message: 'Refresh',
data: {
success: true,
note: `Added: ${status.added} & updated: ${status.updated}`,
},
});
} catch (error) {
systemlog.log({
message: 'Refresh',
type: systemlog.logType.ERROR,
data: {
success: false,
note: error,
},
});
}
}
function findDevice(id) {
return DB('device').findOne({ id }); // this returns is a promise
}
function addDeviceRecord(record) {
return DB('device').insertOne(record); // this returns is a promise
}
function deviceSeen(id) {
return DB('device').updateOne({ id }, { $set: { lastSeen: new Date() } }); // this returns is a promise
}
В качестве альтернативы вы также можете использовать promise.all
, чтобы дождаться выполнения всех обещаний.
async refreshDevices(_timespan) {
const status = {
added: 0,
updated: 0,
};
// Standard API fetch & json() conversion
try {
let response = await fetch(`https://api.example.com/test×pan=${timespan}`)
let data = await response.json();
let promises = data.map(device => {
return new Promise( async (resolve, reject) => {
try {
let record = await findDevice(device._id);
if (!record) {
addDeviceRecord(device);
status.added++;
} else {
deviceSeen(device._id);
status.updated++;
}
resolve();
} catch (error) {
console.log('Error!');
reject(error);
}
});
});
let result = await Promise.all(promises);
systemlog.log({
message: 'Refresh',
data: {
success: true,
note: `Added: ${status.added} & updated: ${status.updated}`,
},
});
} catch (error) {
systemlog.log({
message: 'Refresh',
type: systemlog.logType.ERROR,
data: {
success: false,
note: error,
},
});
}
}
function findDevice(id) {
return DB('device').findOne({ id }); // this returns is a promise
}
function addDeviceRecord(record) {
return DB('device').insertOne(record); // this returns is a promise
}
function deviceSeen(id) {
return DB('device').updateOne({ id }, { $set: { lastSeen: new Date() } }); // this returns is a promise
}