【问题标题】:Lambda Calls DynamoDB DocumentClient Multiple Times through While LoopLambda 通过 While 循环多次调用 DynamoDB DocumentClient
【发布时间】:2019-04-26 11:36:14
【问题描述】:

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

我搜索并找不到有关此问题的任何文档。提前感谢您的阅读。

【问题讨论】:

  • 实际上我再次尝试使用 var,这次我可以从回调函数内部更改它的值。但是,我认为如果我可以将函数传递给回调,而不是像 function(err, data) { ... } 那样以嵌套方式调用回调,代码会更简洁。我尝试传入一个函数而不是进行嵌套,但它无法获取从 documentClient 调用返回的错误和数据。
  • 你用的是什么版本的node.js?

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


【解决方案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 时扫描结束。在这里,它通过将错误对象(异常)作为回调的第一个参数传递给调用者。

  • 最后,如果您被允许使用 Node.js 8.x(或更高版本),您可以使用async/await,这大大简化了异步代码的编写。

【讨论】:

  • 感谢您的回答,有时间我会试试您的代码结构。我正在使用 Node.js 8.x,所以我想我也会尝试 async / await。
  • 请看我关于停止条件的补充
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-30
  • 2015-09-28
相关资源
最近更新 更多