我对AWS Lambda中的Promise链接感到困惑。



exports.handler = async (event) => {
firstMethod = ()=>{
    return new Promise(function(resolve, reject){
        setTimeout(function() {
            resolve({data: '123'})
        }, 2000);
    });

}
secondMethod = (someStuff)=>{
    return new Promise(function(resolve, reject){
        setTimeout(function() {
            resolve({newData:someStuff.data + ' some more data'})
        }, 2000);
    });

}
return new Promise((resolve, reject)=>{
        firstMethod().
        then((data)=>{
            console.log("firtMethod data ",JSON.stringify(data));
            secondMethod(data);
        }).
        then((data)=>{
            console.log("second Method data",JSON.stringify(data));
            resolve("final data",data);
        });

    });

}





我期望上面的代码先获取firstMethod的输出,然后再获取secondMethod的输出。但是我正在获取未定义的第二种方法数据。

最佳答案

主要问题是您对来自firstMethod的诺言的履行处理程序不会返回任何内容。如果希望它从secondMethod返回承诺,以便链等待该承诺,则需要明确地执行以下操作:

firstMethod().
then((data)=>{
    console.log("firtMethod data ",JSON.stringify(data));
    return secondMethod(data);
//  ^^^^^^
}).
then((data)=>{
    console.log("second Method data",JSON.stringify(data));
    resolve("final data",data);
});


但是,您还应该修复其他一些问题。

首先,您没有声明firstMethodsecondMethod,这意味着代码已成为我所谓的“隐式全球性恐怖”的牺牲品。声明变量。

其次,您要向resolve传递多个参数:

resolve("final data",data);


resolve忽略除第一个参数以外的所有参数。

第三,您的代码使用promise creation anti-pattern。您已经有来自firstMethod的承诺,您无需创建新的承诺。只需将您已经拥有的那一台链锁掉。

代替:

return new Promise((resolve, reject)=>{
    firstMethod().
    then((data)=>{
        console.log("firtMethod data ",JSON.stringify(data));
        return secondMethod(data);
    }).
    then((data)=>{
        console.log("second Method data",JSON.stringify(data));
        resolve("final data",data);
    });
});


在非async函数中,您将使用:

return firstMethod().
    then((data)=>{
        console.log("firtMethod data ",JSON.stringify(data));
        return secondMethod(data);
    }).
    then((data)=>{
        console.log("second Method data",JSON.stringify(data));
        return "final data");
    });


这也具有确保拒绝被传回给呼叫者以供呼叫者处理的优点。

但是,由于包装函数是async函数,因此可以使用await而不是显式地使用promise:

exports.handler = async (event) => {
    const firstMethod = ()=>{
        return new Promise(function(resolve, reject){
            setTimeout(function() {
                resolve({data: '123'})
            }, 2000);
        });
    };
    const secondMethod = (someStuff)=>{
        return new Promise(function(resolve, reject){
            setTimeout(function() {
                resolve({newData:someStuff.data + ' some more data'})
            }, 2000);
        });
    };
    const data = await firstMethod();
    console.log("firtMethod data ",JSON.stringify(data));
    await secondMethod(data);
    console.log("second Method data",JSON.stringify(data));
    return "final data";
};

关于javascript - AWS Lambda中的Promise链接,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59327830/

10-09 20:26
查看更多