I've gotten lost inside my own head about how to best structure this function. This code below is mostly correct, I just stubbed out a few of the functions at the bottom, not important.
What is supposed to happen:
- My node app runs at a certain time and calls
refreshDevices() - The function fetches a JSON payload from an API
- The function loops over elements in that payload and checks if there is a record already
- If there is no record, one is created, if there is then it is updated
- After this is run a log entry is created logging the number of changes.
My issue is the log entry happens prior to any of the record checks taking place... my log shows 0 added & 0 updated. I've tried re-writing the code to use an inline async/await function but I think that is effectively the same thing as below.
How am I supposed to structure this function to do what I've said. I am finding the mix of async and sync very confusing to wrap my head around.
- I even tried adding the log entry bit to happen in a
.finally()block at the end, but that was executing before the checks happened. - I have tried this using both
forEachandmap.
refreshDevices(_timespan) {
const status = {
added: 0,
updated: 0,
};
// Standard API fetch & json() conversion
fetch(`https://api.example.com/test×pan=${timespan}`)
.then((response) => response.json())
.then((JSON) => {
JSON.forEach((device) => {
findDevice(device._id)
.then(record => {
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
}
This question