大家感恩节快乐!我正在编写一个调用DynamoDB的lambda函数,并且遇到了设计/实现问题。
我具有以下代码结构:
exports.handler = function(event, context, callback) {
documentClient.batchGet(getParams, function(err, data) {
if (err) {
console.log(err);
} else {
...
while (1) {
documentClient.scan(scanParams, function(err, data)
{
if (err) {
console.log(err);
} else {
...
if (some condition) {
break;
}
}
}
}
}
我无法从documentClient的回调内部调用break
。另外,我不能将变量从documentClient的回调内部传递到外部,然后脱离while循环。我尝试在处理程序范围内创建一个变量,并在documentClient回调函数内为其分配一个值,但是一旦代码超出了回调范围,该值将被擦除,并且该变量在处理程序范围内具有其原始值。
之所以会有一个while循环,是因为如果表很大,扫描将要进行多次尝试。
另外,另一个问题是我想在与处理程序相同的范围内进行回调,而不是在嵌套块之内,例如扫描documentClient的回调函数。但是,我似乎无法将任何数据或变量从嵌套块内部传递到外部。
我搜索了此问题,但找不到任何文档。预先感谢您阅读。
答案 0 :(得分:1)
假设您只能使用Node.js 6.x(不允许使用较新版本),答案是:
// Node.js 6.x answer:
exports.handler = function (event, context, callback) {
documentClient.batchGet(getParams, function (err, data) {
if (err) {
console.log(err);
} else {
// ...
runScan(scanParams, function(err, scanOutput) {
if (err) return callback(err);
// do something with scanOutput.
});
}
});
};
function runScan(scanParams, callback) {
documentClient.scan(scanParams, function (err, data) {
if (err) return callback(err);
if (some_condition) {
var scanOutput = ...;
return callback(null, scanOutput);
}
// Halting condition
if(!data.LastEvaluatedKey) {
return callback(new Error('End of scan'));
}
scanParam.ExclusiveStartKey = data.LastEvaluatedKey;
runScan(scanParams, callback);
});
}
要点:
我将扫描功能移至了自己的功能(runScan()
)。
我们没有使用while循环,而是使用递归:runScan()
调用自身-但使用不同的ExclusiveStartKey
-来扫描下一批项目。
runScan()
是一个异步方法:它不返回传统意义上的值。相反,它需要一个回调函数。如果检测到错误,它将调用callback(err)
(相当于引发异常)。如果它想“返回一个值”给它的调用者,它将调用callback(null, value)
;调用者必须传递一个回调函数(带有两个参数)并分别检查它们。
当没有LastEvaluatedKey
时,扫描结束。在这里,通过将Error对象(异常)作为回调的第一个参数传递给调用者。
最后,如果允许使用Node.js 8.x(或更高版本),则可以使用async
/ await
,这大大简化了异步代码的编写。