Search code examples
aws-lambdaasync-await

await inside a forEach block in Node.js 14.x AWS lambda code


I have an AWS Lambda function in Node.js 14.x that is triggered by SQS and the code needs to process the data and re-publish to a mqtt topic. This is the code I have using async(event);

import { createRequire } from 'module';
const require = createRequire(import.meta.url);
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-west-2'});


var iotParams = {
  topic: 'my-channel',
  qos: 0
};

export const handler = async(event) => {
 
  var msgBody;  

  event.Records.forEach(record => {
    const { body } = record;
    msgBody = body;
    console.log(msgBody);
    
    // for each record, publish the data
      
  
  });
  
  // publish the data
  iotParams.payload = Buffer.from(msgBody);  
  var iotPromise = new AWS.IotData({endpoint: 'a1ilxxxxxxxxx-ats.iot.us-west-2.amazonaws.com'}).publish(iotParams).promise();

  // Handle promise's fulfilled/rejected states
  iotPromise.then(
    function(data) {
      console.log(data);
    }).catch(
      function(err) {
      console.error(err, err.stack);
    }
  );  
  await iotPromise;  

  const response = {
    statusCode: 200,
    body: JSON.stringify('Hello from Lambda!'),
  };
  return response;
};

Since the SQS can pass multiple records (in an array) to lambda, I have to parse and publish the data for each record. So in the above code, I tried to move the mqtt publish code to inside the forEach() loop, but lambda complains about the await inside this loop. What would be the right way to achieve this? I'm not very familiar with async calls...

Thanks in advance Gus


Solution

  • Use for...of instead of forEach in asynchronous code.

    You can read this to learn more.