【问题标题】:AWS Lambda ending early (without any explicit return or callback)AWS Lambda 提前结束(没有任何明确的返回或回调)
【发布时间】:2023-03-16 04:04:01
【问题描述】:

我在将一些 node.js 代码放入 AWS Lambda 时遇到了一点问题。我需要进行几个异步调用,虽然第一个调用的行为与我预期的一样,但 lambda 函数在第二个调用完成之前终止。

返回为 null,这让我认为 lambda 正在达到其隐式回调,但我认为它不应该这样做,因为还有一个尚未解决的承诺。

代码:

exports.handle = async function(event, context) {
  var AWS = require("aws-sdk");

  AWS.config.update({
    region: "eu-west-1",
    endpoint: "dynamodb.eu-west-1.amazonaws.com"
  });

  var docClient = new AWS.DynamoDB.DocumentClient();
  console.log("Scanning Catalogue...");

  var params = {
    TableName : "Catalogue"
  };

  await docClient.scan(params).promise().then(function (data) {
    console.log("Scan succeeded.");
    data.Items.forEach(function (item) {
      //console.log(item.url);
      checkIfUpdateRequired(item);
    })
  })
}

async function checkIfUpdateRequired (catalogueItem) {
  var request = require("request-promise");
  console.log("Getting " + catalogueItem.url);

  await request(catalogueItem.url).then(function(response) {
    console.log(response.statusCode);
    console.log(response.headers['content-type']);
  });

}

日志输出:

START RequestId: 634a55b7-6258-11e8-9f18-6b300c3b5de1 Version: $LATEST
2018-05-28T09:20:44.425Z    634a55b7-6258-11e8-9f18-6b300c3b5de1    Scanning Catalogue...
2018-05-28T09:20:45.446Z    634a55b7-6258-11e8-9f18-6b300c3b5de1    Scan succeeded.
2018-05-28T09:20:47.967Z    634a55b7-6258-11e8-9f18-6b300c3b5de1    Getting https://raw.githubusercontent.com/BSData/wh40k/master/Aeldari%20-%20Craftworlds.cat
2018-05-28T09:20:48.028Z    634a55b7-6258-11e8-9f18-6b300c3b5de1    Getting https://raw.githubusercontent.com/BSData/wh40k/master/Imperium%20-%20Adeptus%20Custodes.cat
END RequestId: 634a55b7-6258-11e8-9f18-6b300c3b5de1
REPORT RequestId: 634a55b7-6258-11e8-9f18-6b300c3b5de1  Duration: 7882.68 ms    Billed Duration: 7900 ms    Memory Size: 128 MB Max Memory Used: 49 MB

所以日志告诉我 checkIfUpdateRequired() 正在被调用,但是 lambda 在承诺被履行之前结束(报告成功,结果值为 null)。我没有对处理程序进行任何手动返回或回调,这似乎是与 lambda 的“提前”结束相关的问题的规范。

我不知所措,谁能给点建议?

【问题讨论】:

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


    【解决方案1】:

    您无需等待checkIfUpdateRequired 承诺完成; docClient.scan 中的所有内容在您的原始代码中都是同步的。使用Promise.all 等待所有承诺完成:

    await docClient.scan(params).promise().then(function (data) {
      console.log("Scan succeeded.");
      return Promise.all(data.Items.map(checkIfUpdateRequired));
    });
    

    请注意,如果您使用的是await,那么如果您习惯性地使用它而不是.then,您的代码将会更扁平且更易于理解。例如,您可以重构为:

    const data = await docClient.scan(params).promise();
    return Promise.all(data.Items.map(checkIfUpdateRequired));
    

    async function checkIfUpdateRequired (catalogueItem) {
      // actually, better to only require once, rather than on every function call
      const request = require("request-promise");
      console.log("Getting " + catalogueItem.url);
      const response = await request(catalogueItem.url)
      console.log(response.statusCode);
      console.log(response.headers['content-type']);
    }
    

    【讨论】:

    • 谢谢,成功了。同意这比我的修补引导我的模式要好得多!在确定需要更新后,我需要更深入一层并从 checkIfUpdateRequired 中进行另一个异步调用。后续调用的 Promise.all 模式是否相同?我在想这样的事情: if (updateRequired) { return Promise.all(doTheUpdate(response)); }
    • 只有当你有一个 Promise 数组时才使用Promise.all。否则,只需返回(或await)单数承诺。 return doTheUpdate(response);
    猜你喜欢
    • 2017-06-10
    • 2021-06-25
    • 2019-10-23
    • 1970-01-01
    • 2021-11-09
    • 2017-10-14
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    相关资源
    最近更新 更多