Lambda通过While循环多次调用DynamoDB DocumentClient

时间:2018-11-23 23:11:21

标签: javascript node.js amazon-web-services aws-lambda amazon-dynamodb

大家感恩节快乐!我正在编写一个调用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的回调函数。但是,我似乎无法将任何数据或变量从嵌套块内部传递到外部。

我搜索了此问题,但找不到任何文档。预先感谢您阅读。

1 个答案:

答案 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,这大大简化了异步代码的编写。

    < / li>