Search code examples
javascriptnode.jsaws-lambdaes6-promise

How to send status 200 callback to api gateway from async lambda , without waiting for lambda execution to complete?


I am creating an async lambda function in Node.Js. There some promised functions used sequentially using Promise.all() .

I have another non-promise function which will send callback to api gateway with status 200. But this non-promise function is waiting for all promised functions to complete and api gateway eventually gets timed out with Endpoint request timed out.

So, how can i send the callback to api gateway from lambda as soon as lambda is triggered?

Lambda Code -

exports.handler = async (event, context, callback) => {
// normal function
function send() {
  console.log('send started');
  const response = {
    statusCode: 200,
    body: JSON.stringify('ok..'),
  };
  callback(null, response);
}
send();
// promised function 1
function timeout1() {
  console.log('Describe Instance started');
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      console.log('timeout complete 1');
    }, 2000);
    resolve();
  });
}
// promised function 2
function timeout2() {
  console.log('Demo function 2');
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      console.log('timeout complete 2');
    }, 3000);
    resolve();
  });
}

try {
  const fn1 = await timeout1();
  const fn2 = await timeout2();
  let promiseFactories = [fn1, fn2];
  Promise.all(promiseFactories).then(() => {
    console.log('Completed');
  });
} catch (error) {
  console.error(error);
}

};


Solution

  • As mentioned in the AWS Documentation:

    For non-async handlers, function execution continues until the event loop is empty or the function times out. The response isn't sent to the invoker until all event loop tasks are finished. If the function times out, an error is returned instead.

    That way, you will need to set the Context.callbackWaitsForEmptyEventLoop property to false which allows it to return regardless of the event loop being empty

    It will follow this structure:

    exports.handler = function(event, context, callback) {
      context.callbackWaitsForEmptyEventLoop = false
      // your code here
    }