gpt4 book ai didi

node.js - 如何在 AWS Lambda 中等待异步操作?

转载 作者:IT老高 更新时间:2023-10-28 21:54:16 25 4
gpt4 key购买 nike

我正在尝试在 S3 中处理上传的文件。由于 getObject 是异步主函数在处理完成之前结束,AWS 在 3-4 秒内杀死 lambda。

更糟糕的是,处理方法中还有异步操作——它会进行 http 调用。

在高层次上,我的代码如下所示:

exports.handler = function(event, context) {
// Get the object from the event and show its content type
var bucket = event.Records[0].s3.bucket.name;
var key = event.Records[0].s3.object.key;
var params = {
Bucket: bucket,
Key: key
};
s3.getObject(params, function(err, data) {
if (err) {
...
} else {
processFile(data.Body.toString(), 0);
console.log("ok");
}
});
//need to wait here till processFile is done
};

processFile = function(content, start) {
... build url to call
http.get(url, function(res) {
console.log("Got response: " + res.statusCode + ");
processFile(content, start + 1);
});
}

我发现nodejs中有异步但亚马逊不包含它; require('async') 或 require('sleep) 都会导致错误。

Lambda 超时配置为 60 秒,但在 3-4 秒后退出。

最佳答案

开发人员的生活在不断变化,现在我们在 lambda 上使用了 NodeJS 8。对于正在查看此内容的任何人,请查看:

Lambda Node 8.10 与 Node 6.10 比较: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/

JS 异步的基础知识: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

更多 aws sdk 示例:https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/using-promises.html

.promise() 方法的详细信息在第一个链接中:https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html#promise-property

这是我对一个基本示例的看法(尝试粘贴到您自己的 lambda 中):

exports.handler = async (event) => {    
function wait(){
return new Promise((resolve, reject) => {
setTimeout(() => resolve("hello"), 2000)
});
}

console.log(await wait());
console.log(await wait());
console.log(await wait());
console.log(await wait());
console.log(await wait());
console.log(await wait());

return 'exiting'
};

以上产出:

enter image description here

如您所见,它等待了 12 秒而没有杀死我的功能 :)

每次等待要多做一件事,使用 Promise.all([]) 语法如下:

exports.handler = async (event) => {
var uploadPromises = [];
folder.files.forEach(file => {
uploadPromises.push( s3.putObject({
Bucket: "mybucket",
Key: file.name,
Body: file.data
}).promise());
});

await Promise.all(uploadPromises);
return 'exiting'
};

下面是原始答案

我手上也有同样的问题。

问题是 javascript 事件循环是空的,所以 Lambda 认为它已经完成了。

这就是我解决这个问题的方法。我意识到这并不理想,我希望有更好的方法,但我不想 a) 添加库,b) 协调 lambda 调用,或 c) 切换到另一种语言。

最终它会起作用。

    exports.handler = (event, context, callback) => {
var response;
var callBackCount;

/*
Ensures the javascript event loop is never empty.
This is the key to keeping lambda from exiting early
*/
setInterval(function(){}, 1000);

/*
Tell lambda to stop when I issue the callback.
This is super important or the lambda funciton will always go until it hits the timeout limit you set.
*/
context.callbackWaitsForEmptyEventLoop = false;

//My way of determining when I'm done with all calls
callBackCount = 0;

//My info to return
response = "";

//Various functions that make rest calls and wait for a response
asyncFunction1();
asyncFunction2();
asyncFunction3();

//Same for asyncFunction 2 and 3
function asyncFunction1(){
response += callBackResponseForThisMethod;

returnResponse();
}

function returnReponse(){
callBackCount++;

if(callBackCount == 3){
//Lambda will stop after this as long as context.callbackWaitsForEmptyEventLoop was set to false
callback(null, JSON.stringify(response));
}
}

};

http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html

关于node.js - 如何在 AWS Lambda 中等待异步操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31633912/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com