我正在尝试使用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
结果。我不知道两者可以同时使用。希望这能帮助到任何和我有类似问题的人。
您有两个选项:
- 将
callbackWaitsForEmptyEventLoop
设置为true,然后AWS将等待,直到事件循环为空 - 等待你的承诺。请注意,您没有等待
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();