当前位置: 首页 > 知识库问答 >
问题:

鉴于所有调用都是异步的,您如何在lambda中构建顺序AWS服务调用?

时恩
2023-03-14

我有java背景,对Lambda所需的Javascript约定有点陌生。

我有一个lambda函数,它可以按照特定的顺序执行几个AWS任务,具体取决于前一个任务的结果。

考虑到每个任务都异步报告其结果,我想知道是否正确的方法可以确保它们都按正确的顺序发生,并且一个操作的结果可供下一个函数调用。

似乎我必须在前一个函数的回调中包含每个函数,但似乎这将进行某种深度嵌套,并想知道这是否是正确的方法。

例如,这些函数中的一个需要DynamoDB getItem,然后调用SNS以获取endpoint,然后调用SNS以发送消息,然后写入DynamoDB。

在lambda javascript中html" target="_blank">执行此操作的正确方法是什么,以解释所有异步性?

共有3个答案

孟树
2023-03-14

我不知道Lambda,但您应该研究节点异步库作为对异步函数进行排序的一种方式。

异步让我的生活变得更轻松,我的代码也更有序,没有你在问题中提到的深度嵌套问题。

典型的异步代码可能如下所示:

async.waterfall([
    function doTheFirstThing(callback) {
         db.somecollection.find({}).toArray(callback);
    },
    function useresult(dbFindResult, callback) {
         do some other stuff  (could be synch or async)
         etc etc etc
         callback(null);
],
function (err) {
    //this last function runs anytime any callback has an error, or if no error
    // then when the last function in the array above invokes callback.
    if (err) { sendForTheCodeDoctor(); }
});

看看上面链接中的异步doco。对于串行、并行、瀑布等有许多有用的函数。Async是主动维护的,看起来非常可靠。

祝你好运

艾星河
2023-03-14

简短回答:

使用Async/Await-并使用. Promise()扩展名调用AWS服务(例如SNS)以告诉aws-sdk使用该服务函数的Promise-tify版本而不是基于回调的版本。

由于要按特定顺序执行它们,因此可以使用Async/Await,前提是从中调用它们的父函数本身是异步的。

例如:

let snsResult = await sns.publish({
    Message: snsPayload,
    MessageStructure: 'json',
    TargetArn: endPointArn
}, async function (err, data) {
    if (err) {
        console.log("SNS Push Failed:");
        console.log(err.stack);
        return;
    }
    console.log('SNS push suceeded: ' + data);
    return data;
}).promise();

重要的部分是。promise()在最后。以下是有关以异步/基于promise的方式使用aws sdk的完整文档:https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/using-promises.html

为了运行另一个aws sdk任务,您将类似地添加wait和。该函数的promise()扩展(假设可用)。

对于任何遇到此线程并实际希望将promise推送到一个数组并等待整个数组完成(不考虑先执行哪个promise)的人,我的结论如下:

let snsPromises = [] // declare array to hold promises
let snsResult = await sns.publish({
    Message: snsPayload,
    MessageStructure: 'json',
    TargetArn: endPointArn
}, async function (err, data) {
    if (err) {
        console.log("Search Push Failed:");
        console.log(err.stack);
        return;
    }
    console.log('Search push suceeded: ' + data);
    return data;
}).promise();

snsPromises.push(snsResult)
await Promise.all(snsPromises)

希望这能帮助那些像我一样通过谷歌偶然发现这一点的人!

邹慈
2023-03-14

我喜欢jonathanbaraldi的回答,但我认为如果你用promise来管理控制流会更好。Q库有一些方便的函数,如nbind,可以帮助将aws sdk之类的节点式回调API转换为promises。

因此,在本例中,我将发送一封电子邮件,然后当电子邮件响应返回时,我将发送第二封电子邮件。这就是所要求的,按顺序调用多个服务。我正在使用promises的then方法以一种垂直可读的方式来管理它。还可以使用catch来处理错误。我认为只要简单地嵌套回调函数,它的可读性就会更好。

var Q = require('q');
var AWS = require('aws-sdk');    
AWS.config.credentials = { "accessKeyId": "AAAA","secretAccessKey": "BBBB"};
AWS.config.region = 'us-east-1';

// Use a promised version of sendEmail
var ses = new AWS.SES({apiVersion: '2010-12-01'});
var sendEmail = Q.nbind(ses.sendEmail, ses);

exports.handler = function(event, context) {

    console.log(event.nome);
    console.log(event.email);
    console.log(event.mensagem);

    var nome = event.nome;
    var email = event.email;
    var mensagem = event.mensagem;

    var to = ['email@company.com.br'];
    var from = 'site@company.com.br';

    // Send email
    mensagem = ""+nome+"||"+email+"||"+mensagem+"";

    console.log(mensagem);

    var params = { 
        Source: from, 
        Destination: { ToAddresses: to },
        Message: {
        Subject: {
            Data: 'Form contact our Site'
        },
        Body: {
            Text: {
                Data: mensagem,
            }
        }
    };

    // Here is the white-meat of the program right here.
    sendEmail(params)
        .then(sendAnotherEmail)
        .then(success)
        .catch(logErrors);

    function sendAnotherEmail(data) {
        console.log("FIRST EMAIL SENT="+data);

        // send a second one.
        return sendEmail(params);
    }

    function logErrors(err) {
        console.log("ERROR="+err, err.stack);
        context.done();
    }

    function success(data) {
        console.log("SECOND EMAIL SENT="+data);
        context.done();
    }
}
 类似资料:
  • 我有一个由S3推送事件触发的AWS Lambda。lambda将调用一个API,这将触发一个长时间运行的进程。我认识到我可以配置S3异步调用lambda函数,因此S3不会等待响应,但我很想知道我是否可以配置lambda异步调用我的API。我不希望lambda在过程完成时等待几分钟。有人能给我指出一些概述这个过程的留档吗?提前谢谢。

  • 我有一个用c#编写的AWS lambda函数。此函数负责调用5-6个API调用(Post请求)。 所有这些API调用都是相互独立的。 我不关心这些API调用的响应。 即使我不关心后续响应,每个API调用也需要大约5秒才能完成。 问题:我希望lambda函数在一秒钟内执行并响应。如何异步进行API调用,使lambda函数能够在我的时间限制内完成所有这些操作,而不必等待API调用的响应?理想情况下,我

  • 问题内容: 我需要从另一个lambda异步调用aws lambda。我有一个用于同步呼叫的工作代码。 但就我而言,“ testLambda”是一个耗时的函数。因为我需要在调用“ testLambda”函数后退出。然后像这样更新代码 它正确返回消息。但是我的’testLambda’函数没有被调用(测试lambda不会生成云监视日志)。与此代码相关的问题是什么。 问题答案: 根据Lambda invo

  • 我在一次调用中有多个对第三方应用程序的同步调用。我正在使用Spring RestTemplate调用第三方应用程序,如下所示, 我的控制员给我打了个电话 现在,当我进行rest调用时,我的rest代码被阻止,直到我从请求的URL获得响应为止。我曾尝试使用AsyncRestTemplate和SimpleReact API,但我面临以下问题。我有一系列的rest调用,我不能在下面的代码中直接提供URL

  • 我有一个聊天应用程序,当我在输入消息后单击按钮时,消息会发布到我的DynamoDB表中。该应用程序应该发布一次消息,但不知何故发布了两次。 管道如下: 客户端单击“发送”按钮-- 在SO的帮助下,我已经将问题隔离到我的Google Cloud函数异步调用Lambda,该函数将Lambda排队两次。 使用async,请求在实际执行之前排队。所以,如果您调用它一次,AWS将检查是否已经有一个正在执行,

  • 我是Firebase的新手,我有很多问题,因为所有的任务都是异步调用的。 谢谢!