I'm new to node js, I'm trying to create a rest method that returns a list of objects, all was fine until I wanted to send the response, the logic does something like this:
what happens is that the point 3 is happening after the point 4 and I got an empty list, after research I found that is due to the async nature of node, I tried to rewrite the code using promises but I could not find an example of a promise that calls another promise
first version
app.get('/initDevices', (req, res) => {
console.log('init devices.');
cameras = [];
onvif.startProbe().then((device_info_list) => {
let requests = device_info_list.map((info) => {
processDevice(info)
});
Promise.all(requests).then(() => {
console.log('all done ');
res.json(cameras);
});
}).catch((error) => {
res.json('nothing');
});
});
function processDevice(info) {
return new Promise((resolve, reject) => {
console.log("step 1");
let device = new onvif.OnvifDevice();
console.log("step 2");
device.init().then((devinfo) => {
console.log("step 3");
cameras.push(devinfo);
console.log("cameras: " + cameras.length);
resolve("done");
}).catch((error) => {
reject("It broke");
});
});
}
output
init devices.
step 1
step 2
//response goes to the user with empty array []
step 3 //push happens
second try (with promises)
function processDevice(info) {
return new Promise((resolve) => {
console.log("step 1");
let device = new onvif.OnvifDevice();
console.log("step 2");
resolve(device);
}).then((device) => {
console.log("step 3");
return device.init();
}).then((device) => {
console.log("step 4");
return cameras.push(device);
});
}
output
init devices.
step 1
step 2
step 3
//response goes to the user with empty array []
step 4 //push happens
I think this line return device.init(); makes the promise to finish but I do not know why.
Can someone help me to understand why the chain doesn't work as expected? what did I do wrong?
by the way, the examples that I followed are here but the operations are just some additions that do not invoke other promises
Edit: I found a better way to achieve this
function processDevice(info) {
let device = new onvif.OnvifDevice();
return device.init().then(() => {
console.log("init done");
cameras.push(camObj);
});
}
since a promise was already being used, it was not necessary to wrap it around another
Your requests
variable is undefined - you have to return the processDevice(info)
inside the map like this:
let requests = device_info_list.map((info) => {
return processDevice(info)
});