提问人:b_a9f 提问时间:11/10/2022 最后编辑:Ermiya Eskandaryb_a9f 更新时间:11/11/2022 访问量:185
Lambda 函数处理程序执行 DynamoDB 更新两次
Lambda function handler executing DynamoDB update twice
问:
我的 Lambda 函数应该增加 dynamodb 表中的值,我使用 .update API 作为原子计数器。 该值递增两次!我尝试更改增量变量值,它总是递增两次。 例如:我的 DynamoDB 表中的值是 2,增量值是 1。我测试了 Lambda 函数,dynamoDB 值为 4(而不是 3)。
相同的代码(没有处理程序函数)在 Lambda 外部成功运行(使用 JS SDK 从 VSCode 执行) 可能是什么问题?
'use strict';
const AWS = require("aws-sdk");
AWS.config.update({ region: "me-central-1" });
const docClient = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event) => {
await docClient.update(
{
TableName: "visitor-counter-table",
Key: {
"visitor-counter": "counter",
},
UpdateExpression: "set #num = #num + :incr",
ExpressionAttributeNames: {
"#num": "number",
},
ExpressionAttributeValues: {
":incr": 1,
},
},
(err, data) => {
err ? console.log(err) : console.log(data);
}
).promise();
return {"statusCode": 200, "body": "number added to DDB Success"}
};
这是我在 VSCode 上运行的代码:
const AWS = require("aws-sdk");
AWS.config.update({ region: "me-central-1" });
const docClient = new AWS.DynamoDB.DocumentClient();
docClient.update(
{
TableName: "visitor-counter-tbl",
Key: {
"visitor-counter": "counter",
},
UpdateExpression: "set #num = #num + :incr",
ExpressionAttributeNames: {
"#num": "number",
},
ExpressionAttributeValues: {
":incr": 1,
},
},
(err, data) => {
err ? console.log(err) : console.log(data);
}
);
答:
1赞
Ermiya Eskandary
11/11/2022
#1
您将成功和失败回调传递给您,同时获取并等待生成的 promise。docClient.update
这意味着您最终会触发两次更新。
本地调用之所以有效,是因为您只是传递回调,而不是请求 promise () 然后等待它。这会导致触发一次更新。.promise()
要么使用 await,要么使用回调 - 不要两者兼而有之。
这应该有效:
await docClient.update(
{
TableName: "visitor-counter-table",
Key: {
"visitor-counter": "counter",
},
UpdateExpression: "set #num = #num + :incr",
ExpressionAttributeNames: {
"#num": "number",
},
ExpressionAttributeValues: {
":incr": 1,
},
}
).promise();
评论
1赞
jarmod
11/11/2022
这很有趣。我想知道为什么会这样。为什么同时提供回调函数和请求 promise 会导致 2 倍的 API 请求?这似乎是 AWS 开发工具包中的一个错误,或者至少是一个非常可疑的结果,如果可能的话,值得预防。我几乎可以理解 1x API 请求的两个完成(一个是已履行的承诺,另一个是回调),但不能理解 2x API 请求。可能需要深入研究此处的代码才能了解更多信息。
1赞
jarmod
11/11/2022
好的,调用 将返回一个 AWSRequest 对象,您必须调用该对象才能实际发送 API 请求。但是调用实际执行,因此回调函数的存在会发送 API 请求。现在,该方法的代码“发送请求并返回一个 promise”,因此它也发送了请求。这就是为什么如果 callback 和 promise() 都存在,API 调用会发生两次。service.action(params)
.send()
service.action(params, callback)
if (callback) request.send(callback)
.promise()
评论