我正在尝试使用Lambda函数实现一个简单的计数器,但是每当我对其进行测试时,下面的updateItem都不起作用:回调中的所有log语句都不会运行,当然还有相关的计数器在表中永远不会更新。这是我的lambda函数:
'use strict';
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB({ apiVersion: '2012-08-10' });
let params = {
TableName: 'Counters',
Key: {
'name': { S: 'global' }
},
UpdateExpression: 'SET val = val + :inc',
ExpressionAttributeValues: {
':inc': { N: '1' }
},
ReturnValues: 'ALL_NEW'
};
exports.handler = async(event) => {
console.log("Invoked counter-test");
dynamodb.updateItem(params, function(err, data) {
console.log("In updateItem callback");
if (err)
console.log(err, err.stack);
else
console.log(data);
});
console.log("Updated counter");
const response = {
statusCode: 200,
body: JSON.stringify('Counter updated'),
};
return response;
};
这是测试的输出:
Response:
{
"statusCode": 200,
"body": "\"Counter updated\""
}
Request ID:
"80e92299-2eea-45e4-9c68-54ccf87199c5"
Function Logs:
START RequestId: 80e92299-2eea-45e4-9c68-54ccf87199c5 Version: $LATEST
2019-05-07T11:34:21.931Z 80e92299-2eea-45e4-9c68-54ccf87199c5 Invoked counter-test
2019-05-07T11:34:21.934Z 80e92299-2eea-45e4-9c68-54ccf87199c5 Updated counter
END RequestId: 80e92299-2eea-45e4-9c68-54ccf87199c5
REPORT RequestId: 80e92299-2eea-45e4-9c68-54ccf87199c5 Duration: 275.91 ms Billed Duration: 300 ms Memory Size: 128 MB Max Memory Used: 67 MB
如您所见,没有运行来自updateItems回调的日志语句。
如果我尝试使用aws dynamodb
从命令行更新计数器,则它确实可以工作,但是:
$ aws dynamodb update-item \
--table-name Counters \
--key '{"name": { "S": "global" }}' \
--update-expression 'SET val = val + :inc' \
--expression-attribute-values '{":inc": {"N": "1"}}' \
--return-values ALL_NEW \
--output json
{
"Attributes": {
"name": {
"S": "global"
},
"val": {
"N": "129"
}
}
}
答案 0 :(得分:4)
这是由于Java语言的异步特性。
方法updateItem
是异步的,您不必等待回调被触发再返回(您开始updateItem
操作,然后立即返回响应)。
如果要维护回调模式,则应执行以下操作:
exports.handler = (event, context, callback) => {
console.log("Invoked counter-test");
dynamodb.updateItem(params, function(err, data) {
console.log("In updateItem callback");
if (err) {
console.log(err, err.stack);
callback(err);
} else {
console.log(data);
console.log("Updated counter");
const response = {
statusCode: 200,
body: JSON.stringify('Counter updated'),
};
callback(null, response);
}
});
};
使用承诺:
exports.handler = (event, context, callback) => {
console.log("Invoked counter-test");
dynamodb.updateItem(params).promise()
.then((data) => {
console.log(data);
console.log("Updated counter");
const response = {
statusCode: 200,
body: JSON.stringify('Counter updated'),
};
callback(null, response);
});
.catch((err) => {
console.log(err, err.stack);
callback(err);
})
};
使用await
(推荐):
exports.handler = async (event) => {
try {
console.log("Invoked counter-test");
const data = await dynamodb.updateItem(params).promise();
console.log(data);
console.log("Updated counter");
const response = {
statusCode: 200,
body: JSON.stringify('Counter updated'),
};
return response;
} catch (err) {
console.log(err, err.stack);
throw err;
}
};
另请参见Understanding Asynchronous JavaScript,Deeply Understanding JavaScript Async and Await with Examples和AWS SDK for Javascript - Using JavaScript Promises。