如何链接调用节点js中另一个承诺的承诺

How to chain a promise that calls another promise in node js

我是节点 js 的新手,我正在尝试创建一个 return 对象列表的休息方法,一切都很好,直到我想发送响应,逻辑做这样的事情:

  1. 找对象
  2. 初始化对象
  3. 将对象推入列表
  4. 发送包含对象的列表

发生的事情是第 3 点发生在第 4 点之后,我得到一个空列表,经过研究我发现这是由于节点的异步性质,我尝试使用 promises 重写代码但我可以找不到调用另一个承诺的承诺示例

第一个版本

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");
        });
    });
}

输出

 init devices.
 step 1
 step 2
 //response goes to the user with empty array []
 step 3 //push happens

第二次尝试(承诺)

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);
    });
}

输出

init devices.
step 1
step 2
step 3
//response goes to the user with empty array []
step 4 //push happens

我认为这一行return device.init();承诺完成但我不知道为什么。

有人能帮我理解为什么链不能按预期工作吗? 我做错了什么?

顺便说一句,我遵循的示例是 here 但这些操作只是一些不调用其他承诺的补充

编辑:我找到了更好的实现方法

function processDevice(info) {
    let device = new onvif.OnvifDevice();
    return device.init().then(() => {
        console.log("init done");
        cameras.push(camObj);
    });
}

因为已经使用了一个承诺,所以没有必要将它包裹在另一个承诺中

您的 requests 变量未定义 - 您必须 return 地图内的 processDevice(info) 如下所示:

let requests = device_info_list.map((info) => {
            return processDevice(info)
        });