用Lambda查询DynamoDB什么也不做

我有一个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(); }; 

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

 { "cognitoID": { "S": "token" }, "email": { "S": "user1@domain.com" }, "password": { "S": "somepassword" }, "tos_aggreement": { "BOOL": true }, "userID": { "S": "user1" } } 

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

我试着做没有callback的getItem(params),然后定义callback完成,成功和失败,但是当我做send()时,即使是完整的callback也不会被调用。

我知道这些调用是asynchronous的,我想也许,lambda函数完成之前查询完成,因此callback将不会被调用,但是,我添加了一个简单的愚蠢的循环在函数的结尾和调用timed 3秒后,没有callback被称为。

我试着用不同的函数batchGetItem,getItem,listTables和scan。 结果是一样的,没有错误,但callback函数永远不会被调用。

我敢打赌,如果我查询dynamoDB而不使用Lambda它会得到我的结果,所以我真的想知道为什么这里没有发生。

我为这个函数创build了一个angular色,我创build了一个策略,允许访问dynamoDB中我需要的function,但无济于事。

政策如下所示:

 { "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": "*" } ] } 

我在模拟器中运行了这个策略,它按我的想法工作。 build议?

所以,原来的代码是正确的。 问题是dynamodb API使用了所有的callback函数,基本上函数在数据被检索之前结束。

最快的解决方法是删除context.succeed()调用,数据将被检索。 当然,使用asynchronous模块会有所帮助,如果你不想使用它,只需要在你的callback中添加一个计数器或布尔值,然后等待值改变,表明callback已经被调用(哪种types的如果你想到的话)

我有一些类似的问题,没有find很多有用的资源。 这是我最终做的。 也许有人更聪明可以告诉我们,如果这是最好的。

 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); }); 

总而言之,通过主函数callback回函给较小的函数,允许应用程序继续,直到完成Dynamo。 保持context.succeed在辅助function或继续在那里的其他function。

我的问题是,我的lambda运行在一个VPC为了连接到ElastiCache。 这会导致对公共Internet资源(如DynamoDB和API网关)的任何查询无限期地挂起。 为了访问DynamoDB,我必须在VPC中设置一个NAT网关。

为了避免callback地狱,使用承诺。 funfunfunction这个人在YouTube上有一些相当不错的教程。