首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何等待AWS中的异步操作?

如何等待AWS中的异步操作?
EN

Stack Overflow用户
提问于 2015-07-26 05:18:24
回答 7查看 92K关注 0票数 66

我正试图在S3中处理上传的文件。因为getObject是异步的主函数,所以在处理之前结束,AWS在3-4秒内杀死lambda。

更糟糕的是,处理方法中还包含异步操作--它进行http调用。

在较高级别上,我的代码如下所示:

代码语言:javascript
复制
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中有异步,但是amazon没有包含它;两者都需要(‘异步’)或要求(‘睡眠’)会导致错误。

Lambda超时配置为60秒,但它在3-4秒内退出.

EN

回答 7

Stack Overflow用户

发布于 2017-02-12 02:00:47

开发人员的寿命在不断变化,现在我们在lambda上有了NodeJS 8。现在看这个的人请看一下:

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

JS异步的基础知识:函数

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

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

下面是一个基本示例(尝试粘贴到您自己的lambda中):

代码语言:javascript
复制
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'
};

上述收益率:

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

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

代码语言:javascript
复制
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)切换到另一种语言。

在一天结束的时候,它起作用了。

代码语言:javascript
复制
    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

票数 56
EN

Stack Overflow用户

发布于 2018-04-30 16:51:32

使用异步/等待

代码语言:javascript
复制
let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();
let data;
exports.handler = async (event) => {
    try {
        data = await lambda.getAccountSettings().promise();
    }
    catch (err) {
        console.log(err);
        return err;
    }
    return data;
};
票数 14
EN

Stack Overflow用户

发布于 2015-12-28 03:53:26

不包括async,但这并不意味着您不能自己添加它。只需在本地添加包(npm install async),并在上传Lambda函数之前将node_modules文件夹包含在ZIP中。

如果您希望单独处理开发依赖项(例如: test、aws-sdk以在本地执行您的函数,等等),您可以在package.json中的devDependencies下添加它们。另外,如果您想要自动化开发、测试、部署和提升代码的过程,那么这两个repos将非常方便。

测试、打包和部署lambda的Grunt例程

用于运行和部署lambda函数的命令行工具

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31633912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档