Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
140 views
in Technique[技术] by (71.8m points)

javascript - Variables inside of Lambda Promise inside of async function w/ Promise.all

I've wasted two days trying to find an answer to this. I have reduced my code to mostly pseudo code for simplicity.

I need to have an async function that is called as a trigger from an SQS queue. The code loops through the 10 SQS records sent and for each it calls Twilio and uses the promise format. I want to build an array during this process so that at the end I can do a batch write to DynamoDB.

I can't figure out how to maintain/add to an array inside of the Twilio promise THEN that is readable outside/later.

exports.handler =  async function(event, context) {
    let messages = [];
    
    //LOOP THROUGH SQS RECORDS
    event.Records.forEach(record => {
        //QUERY DYNAMO FOR DUPLICATES
        
        //IF NOT A DUPLICATE
        twilio.messages.create({
            body: event.text,
            to: event.phone,
            from: '+15005550006'
        })
        .then((message) => {
            //ADD MESSAGE TO STATUS SQS
            
            //CREATE ARRAY FOR ENTRY INTO DYNAMODB BATCH WRITE
            var item = {
                PutRequest: {
                  Item: {
                    'msgid': { S: msgid },
                    'text': { S: text },
                    'phone': { S: phone },
                    'date': { S: now }
                    }  
                }
            };
        });
        //END IF NOT A DUPLICATE
    });
    
    //BATCH WRITE TO DYNAMO OF ALL ITEMS IN MESSAGES ARRAY
};

EDIT: This is the actual code based on suggestions. Nothing is logged on either console.log, not even the "message". Currently just trying to get anything from then to be returned in Promise.all. Actually need to return the messages array but trying to get SOMETHING to return.

    let messages = [];
    
    var messagePromises = event.Records.map(record => { 
        var text = record.body;
        var phone = record.messageAttributes["phone"].stringValue;
        var msgserviceid = record.messageAttributes["msgserviceid"].stringValue;
        var userid = record.messageAttributes["userid"].stringValue;
        var credits = record.messageAttributes["credits"].stringValue;
        var item = [];
    
        var payload = {
            "phone": phone,
            "text": text,
            "msgserviceid": msgserviceid
        };
        
      return twilio.messages.create({
                body: text,
                to: phone,
                from: '+15005550006'
            }).then((message) => {
                var msgid = message.sid;

                var now = new Date().toISOString().slice(0, 19).replace('T', ' ');
                
                var item = {
                    PutRequest: {
                      Item: {
                        'msgid': { S: msgid },
                        'text': { S: text },
                        'phone': { S: phone }
                        }  
                    }
                };
                
                messages.push(item);
                
                console.log("message", message);
                return message;
            }).catch((error) => {
                console.log("error", error);
            });
    });
    
    Promise.all(messagePromises).then((values) => {
        console.log(values);
    });
};```
question from:https://stackoverflow.com/questions/65600579/variables-inside-of-lambda-promise-inside-of-async-function-w-promise-all

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Map all the promises into an array. And use promise all to know when they are done.

var messagePromises = event.Records.map(record => { 
  return twilio.messages
    .create({...})
    .then((message => {
       return {
         whatever: "you want to return";
       };
    });
});


Promise.all(messagePromises).then((values) => {
  console.log(values);
});

Basic idea....

const twilio = {
  messages: {
    create: (foo) => {
      return new Promise((resolve) => {
        var num = Math.floor(Math.random() * 3000);
        window.setTimeout(() => resolve({
          [foo]: num
        }), num);
      });
    }
  }
};


const event = {
  Records: [{
    name: 'Foo'
  }, {
    name: 'bar'
  }, {
    name: 'Baz'
  }]
};

var messagePromises = event.Records.map(record => {
  return twilio.messages
    .create(record.name)
    .then((message) => {
      console.log(message);
      return message;
    });
});


Promise.all(messagePromises).then((values) => {
  console.log(values);
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...