如何链接一个在节点js中调用另一个promise的promise

时间:2018-01-25 01:08:19

标签: javascript node.js promise chain

我是节点js的新手,我正在尝试创建一个返回对象列表的rest方法,一切都很好,直到我想发送响应,逻辑执行如下操作:

  1. 查找对象
  2. 初始化对象
  3. 将对象推入列表
  4. 发送带有对象的列表
  5. 发生的事情是点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
    

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

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

    顺便说一下,我遵循的例子是here,但操作只是一些不会引用其他承诺的附加内容

    编辑:我找到了更好的方法来实现这个目标

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

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

1 个答案:

答案 0 :(得分:1)

您的requests变量未定义 - 您必须在地图中返回processDevice(info),如下所示:

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