【问题标题】:AWS Lambda returning without waiting for promisesAWS Lambda 无需等待承诺即可返回
【发布时间】:2017-12-15 02:30:51
【问题描述】:

我有一个功能在节点环境中运行良好。该函数使用 Promise、S3 调用和 then 和 catch 调用回调,其中包含相关的 200/500 statusCode 和消息正文。

现在我将其部署为 lambda 函数,并在其周围有一个包装器,如下所示:

module.exports.getAvailableDates = (event, context, callback) => {
  const lambdaParams = retrieveParametersFromEvent(event);
  console.log(`Got the criteria`);
  module.exports.getFilteredDates(lambdaParams.startDate,
                                 lambdaParams.endDate, callback);
  console.log(`Returning without the internal function results`);
};

内部函数如下所示:

module.exports.function getFilteredDates(startDate, endDate) {
  const dateSet = new Set();
  return new Promise((resolve, reject) => {
    const getAllDates = (isDone) => {
      if (isDone) {
        const Dates = Array.from(dateSet).join();
        resolve(Dates);
        return;
      }
      getTestedDates(startDate, endDate, region, func, memory,
        lastDateKey, dateSet).then(getAllDates).catch((error) => {
          reject(error);
        });
    };
    lastDateKey = '';
    getTestedDates(startDate, endDate, region, func, memory,
      lastDateKey, dateSet).then(getAllDates).catch((error) => {
        reject(error);
      });
  });
}

更内部的函数看起来很相似,只是它实际查询 S3 数据库并从中返回与日期条件匹配的键列表。

在 AWS CloudWatch 日志中,我看到了两个打印件,并且仅在它们之后是内部函数输出。我的理解是 lambda 函数并没有等待带有承诺的内部函数实际完成它的工作(包括内部等待承诺)并且返回给我一个错误的状态。我能做什么?

【问题讨论】:

  • 你能分享你的promise代码

标签: javascript amazon-web-services aws-lambda es6-promise


【解决方案1】:

在执行callback 之前执行最后一个console.log

如果您想在退出 Lambda 之前打印完整的语句,则需要包装 callback 广告等待 Promise 完成:

import getFilteredDates from '../path/to/file';

module.exports.getAvailableDates = (event, context, callback) => {
  const lambdaParams = retrieveParametersFromEvent(event);
  console.log(`Got the criteria`);
  getFilteredDates(lambdaParams.startDate,lambdaParams.endDate)
  .then( result => {

    console.log(`Returning the internal function results`);
    return callback();
  })
  .catch(callback);
};

我已更新代码以使用以下功能的 Promises。

你的getFilteredDates 需要重新调整一下:

  • 您要么拥有第三个参数来接受内部回调并在内部处理 Promise 链
  • 或者您公开一个 Promise 并在主范围内从外部处理回调。

让我们将它重构为只返回一个 Promise 并在外部处理回调:

  function getFilteredDates(startDate, endDate) {
    const dateSet = new Set();
    return new Promise((resolve, reject) => {
      const getAllDates = (isDone) => {
        if (isDone) {
          const Dates = Array.from(dateSet).join();
          resolve(Dates);
          return;
        }
        getTestedDates(startDate, endDate, region, func, memory,
          lastDateKey, dateSet).then(getAllDates).catch((error) => {
          reject(error);
        });
    };
    lastDateKey = '';
    getTestedDates(startDate, endDate, region, func, memory,
      lastDateKey, dateSet).then(getAllDates).catch((error) => {
      reject(error);
    });
  });
}
module.exports = getFilteredDates;

【讨论】:

  • 我认为我们中的一个错了另一个。我的问题不是打印,而是 lambda 在没有等待回调的情况下返回,这是在我的内部 getFilteredDates 函数中调用的。
  • 嗨,Marco,像以前一样 - 这对我在节点(本地)中有效,但在部署为 lambda 时无效。很奇怪……
  • 你在使用不支持 promise 的 node sdk 吗?
  • 您在 Lambda 中使用什么版本的节点?
  • runtime: nodejs6.10 我在该服务中有一个不同的 lambda,它 确实 等待在完全相同的机制下实现承诺。我正在努力寻找差异。
【解决方案2】:

好的,想通了,这是我的错。使用状态代码调用回调的内部函数在返回 200(成功)时没有null,并且一次又一次地失败了 lambda。无论如何,我将我的 lambda 重写为:

module.exports.getAvailableDates = (event, context, callback) => {
  const lambdaParams = retrieveParametersFromEvent(event);
  getFilteredDates(lambdaParams.startDate, lambdaParams.endDate)
    .then(Dates => callback(null, { statusCode: 200, body: Dates}))
    .catch(error => callback({ statusCode: 500, body: error}));
};

现在它工作正常。感谢任何尝试提供帮助的人!

奥伦

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 2013-05-01
    • 2018-09-10
    • 1970-01-01
    • 2019-03-20
    • 1970-01-01
    • 2014-11-04
    相关资源
    最近更新 更多