Async/await不工作AWS lambda,在等待之后跳过所有内容



我正在尝试使用AWS lambda来测试使用axios的几个API调用,但是遇到了一些问题。我遇到的每一篇帖子都说,在Lambda中处理承诺的最佳方式是使用async/await而不是.then,所以我做出了改变。当我使用node运行程序时,它运行得很好,但当我在本地调用Lambda时,似乎跳过了axios调用之后的所有内容。当我在没有await的情况下本地调用Lambda时,它之后的调用运行良好,但随后我被迫使用.then,Lambda无论如何都不会等待。我已经将Lambda超时增加到900,并且每次都在sam invoke local之前运行sam build

function checkServers() {
console.log("Inside checkServer");
console.log("Before apis to test");
// apisToTest has length of 2
apisToTest.forEach(async (apiToTest) => {
console.log("Api to test");
let res = await axios(apiToTest)
console.log("x"); // This gets skipped
console.log(res); // This gets skipped
})
console.log("After api to test")
}
exports.lambdaHandler = async (event, context) => {
console.log("Inside lambda handler");
checkServers();
console.log("After lambda handler");
};
// Used to test app using node command
checkServers()

这会产生以下输出:

INFO    Inside lambda handler     
INFO    Inside checkServer        
INFO    Before apis to test       
INFO    Api to test
INFO    Api to test
INFO    After api to test
INFO    After lambda handler

感谢您的回复,不幸的是,这些并不是我用例的理想解决方案,尽管它们对我提出解决方案非常有帮助。

async function checkServers() {
let emailBody = "";
let callResult = "";
let completedCalls = 0;
let promises = [];
for (const apiToTest of apisToTest) {
await axios(apiToTest).then((res) => {
// Do something
}).catch((r) => {
// Handle error
})
}
}
exports.lambdaHandler = async (event, context) => {
context.callbackWaitsForEmptyEventLoop = true;
await checkServers();
};

总之,我将forEach调用替换为for...of调用,将checkServers更改为async,并将await.then().catch组合以处理Promise结果。我不知道两者可以同时使用。希望这能帮助到任何和我有类似问题的人。

您有两个选项:

  1. callbackWaitsForEmptyEventLoop设置为true,然后AWS将等待,直到事件循环为空
  2. 等待你的承诺。请注意,您没有等待checkServers上的承诺。考虑使用await Promise.all([...])来等待所有的承诺完成

注意:如果您将再次运行lambda,则来自以前调用的事件可能";"泄漏";到下一次调用。您可以在此处了解:https://lumigo.io/blog/node-js-lambda-execution-leaks-a-practical-guide/

披露:我在发布这篇博客文章的公司工作

与saart所说的类似,您可以尝试以下代码,看看它是否有效:

async function checkServers() {
const promises = apisToTest.map((apiToTest) => axios(apiToTest))
const resolvedPromises = await Promise.all(promises);
return resolvedPromises;
}
exports.lambdaHandler = async (event, context) => {
try {
const result = await checkServers();
console.log(result);
} catch (error) {
console.log(error)
}

};
// Used to test app using node command
checkServers();

最新更新