使用Lambda查询DynamoDB什么都不做

E.T*_*E.T 16 javascript callback node.js amazon-dynamodb aws-lambda

我有一个Lambda函数的以下代码:

console.log('Loading function');
var aws = require('aws-sdk');
var ddb = new aws.DynamoDB();

function getUser(userid) {
    var q = ddb.getItem({
        TableName: "Users",
        Key: {
            userID: { S: userid } }
        }, function(err, data) {
            if (err) {
                console.log(err);
                return err;
            }
            else {
                console.log(data);
            }
    });
    console.log(q);
}


exports.handler = function(event, context) {
    console.log('Received event');
    getUser('user1');
    console.log("called DynamoDB");
    context.succeed();
};
Run Code Online (Sandbox Code Playgroud)

我有一个[Users]表定义如下:

{
    "cognitoID": { "S": "token" },
    "email": { "S": "user1@domain.com" },
    "password": { "S": "somepassword" },
    "tos_aggreement": { "BOOL": true },
    "userID": { "S": "user1" }
}
Run Code Online (Sandbox Code Playgroud)

当我调用该函数时(从AWS控制台或CLI),我可以看到日志中的消息,但从不调用getItem()的回调.

我尝试了没有回调的getItem(params),然后定义了完成,成功和失败的回调,但是当我执行send()时,甚至也没有调用完整的回调.

我知道调用是异步的,我想也许,lambda函数在查询完成之前完成,因此不会调用回调,但是,我在函数末尾添加了一个简单的愚蠢循环,并且调用了timed 3秒后退出,根本没有调用回调.

我尝试了不同的函数batchGetItem,getItem,listTables和scan.结果相同,没有错误,但从不调用回调函数.

我敢打赌,如果我在不使用Lambda的情况下查询dynamoDB,它会得到结果,所以我真的想知道为什么这里什么也没发生.

我为该函数创建了一个角色,并创建了一个策略,允许访问我需要的dynamoDB中的功能但无济于事.

该政策如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": "arn:aws:lambda:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:BatchGetItem",
                "dynamodb:Scan",
                "dynamodb:PutItem",
                "dynamodb:Query",
                "dynamodb:GetRecords",
                "dynamodb:ListTables"
            ],
            "Resource": "arn:aws:dynamodb:*:*:*"
        },
        {
            "Action": [
                "logs:*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我在模拟器中运行了策略,它按照我的想法运行.建议?

E.T*_*E.T 17

因此,事实证明代码是正确的.问题是dynamodb API使用所有这些回调,基本上函数在检索数据之前结束.

最快的解决方法是删除context.succeed()呼叫,并检索数据.当然使用异步模块会有所帮助,如果你不想使用它,只需在你的回调中添加一个计数器或一个布尔值,然后等到值发生变化,表明已经调用了回调(哪种类型很糟糕)如果你想到它)

  • 我认为最好从回调函数中调用`context.succeed()`,而不是添加计数器和循环,如下所示:console.log(data); context.succeed(数据); (7认同)

小智 5

我有一些类似的问题,并没有找到很多有用的资源.这就是我最终做的事情.可能有些聪明的人可以告诉我们这是否是最好的.

function getHighScores(callback) {
    var params = {
        TableName : 'sessions',
        ScanFilter: {"score":{"AttributeValueList":[{"N":"0"}], "ComparisonOperator":"GT"}},
    };
    var dynamo = new AWS.DynamoDB();
    dynamo.scan(params, function(err, data) {
        if (err) {
            console.log (err)
            callback(err);
        } else {
            callback(data.Items);
            console.log(data.Items);
        }
    });
} 



getHighScores(function (data) {
    console.log(data);
    context.succeed(data);
});
Run Code Online (Sandbox Code Playgroud)

总之,通过main函数回调回调到较小的函数,允许应用程序继续运行直到完成Dynamo.将context.succeed保留在辅助函数中或继续其他函数.