有没有办法从 node.js 同步调用 AWS Lambda?

Posted

技术标签:

【中文标题】有没有办法从 node.js 同步调用 AWS Lambda?【英文标题】:Is there a way to invoke AWS Lambda synchronously from node.js? 【发布时间】:2018-06-26 14:02:44 【问题描述】:

我正在尝试通过 AWS Lambda 从现有应用程序运行特定函数,使用 JS 开发工具包从我的 node.js 应用程序调用 Lambda。由于我要覆盖现有函数,因此我必须保留其基本结构,即:

overwrittenFunction = function(params) 
    //get some data
    return dataArray;

..所以我需要一个可以返回的数组,如果我想保持我使用的 lib 的底层结构相同。现在据我所知,Lambda 调用是异步的,因此不可能执行以下操作:

overwrittenFunction = function(params) 
    lambda.invoke(params, callback);
    function callback(err,data) 
        var dataArray = data;
    
    return dataArray;

(我也用 promises 和 async/await 尝试过类似的事情)。

afaik 我现在有两个选择:以某种方式弄清楚如何进行同步 Lambda 调用,或者修改我的库/现有应用程序(如果可能的话,我宁愿不这样做)。

有没有办法做这样的事情并以某种方式返回我期望的值?

(我使用的是节点 v8.9.4)

【问题讨论】:

你使用的是什么版本的node @dashmug 我正在使用 v8.9.4 【参考方案1】:

您可以使用异步等待,但由于 AWS 开发工具包使用节点回调模式,您需要使用内置的 promisify 包装函数。

const promisify = require('utils').promisify 
const aws = require('aws-sdk');

const lambda = aws.Lambda();
const invoke = promisify(lambda.invoke);

async function invocation(params) 
  try 
    return await invoke(params);
   catch (err) 
    throw new Error('Somethings up');
  


const data = invocation(params);

【讨论】:

但是异步函数不总是返回一个承诺吗?我的问题是我不能以一种让我将它们的值“返回”到函数之外的方式来处理承诺:/ 你试过了吗? 我做了,它抛出一个错误:this.makeRequest 不是一个函数。 ||如果我理解正确,那么在这种情况下,您正试图让 lambda 调用返回一个承诺,对吧? Afaik,通过使用 lambda.invoke().promise()(我尝试过)在 SDK 中本机工作 这就是应该如何避免“this.makeRequest is not a function”错误const invoke = promisify(lambda.invoke.bind(lambda));另外导入需要const promisify = require('util').promisify;它是'util'而不是'utils' 【参考方案2】:

Lambda 和 async/await 有点棘手,但以下对我有用(在生产中):

const lambdaParams = 
    FunctionName: 'my-lambda',
    // RequestResponse is important here. Without it we won't get the result Payload
    InvocationType: 'RequestResponse',
    LogType: 'Tail', // other option is 'None'
    Payload: 
        something: 'anything'
    
;

// Lambda expects the Payload to be stringified JSON
lambdaParams.Payload = JSON.stringify(lambdaParams.Payload);

const lambdaResult = await lambda.invoke(lambdaParams).promise();

logger.debug('Lambda completed, result: ', lambdaResult.Payload);

const resultObject = JSON.parse(lambdaResult.Payload)

用 try/catch 把这一切包起来,然后去镇上。

【讨论】:

我们可以在这里调用.promise(),因为大多数SDK操作返回一个AWS.Request对象:docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/… 如何处理长请求?节点会超时吗? 非常有帮助,谢谢。值得更多关注 InvocationType: 'RequestResponse', 我认为 - 这是我所缺少的拼图

以上是关于有没有办法从 node.js 同步调用 AWS Lambda?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Node.js 从 AWS Lambda 函数连接到 MySql 数据库,没有连接回调

从本地系统而不是S3上运行的node.js应用程序调用AWS Lambda

使用 node.js 从 C++ 调用 JavaScript

如何使用订阅和 AWS AppSync 高效同步 Apollo 的缓存

从 Node.js 连接到 SQL 数据库 (AWS RDS) 而没有 ETIMEDOUT 错误

Node.js中的代码AWS Lambda Package不会调用putRecord()来将数据添加到AWS Kinesis Firehose Stream中