Функция обратного вызова setImmediate () не вызывается в AWS Lambda с использованием узла 8.10 - PullRequest
0 голосов
/ 08 ноября 2018

Я хотел бы понять, почему обратный вызов setImmediate не вызывается в следующих случаях:

module.exports.handler = async (event, context, callback) => {
  try {
    console.log('calling setImmediate...');
    setImmediate(function () {
      console.log('setImmediate callback invoked!');
      callback(null, 'OK!!!!');
    })
  } catch (e) {
    console.log('Failed!');
    console.log(e);
    callback(e);
  }
};

Вывод в CloudWatch выглядит следующим образом:

START RequestId: c2b83f7b-e37a-11e8-ba70-5b99f76ce7ed Version: $LATEST
2018-11-08T17:21:42.922Z    c2b83f7b-e37a-11e8-ba70-5b99f76ce7ed    calling setImmediate...
END RequestId: c2b83f7b-e37a-11e8-ba70-5b99f76ce7ed
REPORT RequestId: c2b83f7b-e37a-11e8-ba70-5b99f76ce7ed  Duration: 35.99 ms  Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 19 MB

Удаление ключевого слова async исправляет его , но я не понимаю, почему.

Я пытался воспроизвести это поведение вне лямбда-окружения:

async function test(){
  setImmediate(function(){
    console.log('setImmediate callback!')
  })
}

test()

Но в этом примере вызывается обратный вызов.

Кто-нибудь может указать мне правильное направление, чтобы понять это?

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Если вы возвращаете обещание, что делают функции async, ваша лямбда заканчивается, когда обещание разрешается. Поскольку ваша асинхронная функция не содержит выражений await, возвращаемое обещание разрешается немедленно. Вы не можете принять обратный вызов и вернуть обещание.

Для await на setImmediate необходимо создать обещание, которое разрешается при срабатывании обратного вызова. Преобразование вашего callback(e) в отклоненное обещание и вашего callback(null, 'OK!!!!') в разрешенное обещание:

module.exports.handler = async (event, context) => {
  try {
    console.log('calling setImmediate...');
    return await new Promise((resolve, reject) => {
      setImmediate(function () {
        console.log('setImmediate callback invoked!');
        resolve('OK!!!!');
      });
    });
  } catch (e) {
    console.log('Failed!');
    console.log(e);
    throw e;
  }
};
0 голосов
/ 09 ноября 2018

Вы не должны использовать обратный вызов при использовании обработчиков асинхронных вызовов в Узле 8.

Функции, объявленные как асинхронные в Узле 8, фактически возвращают обещание.Поскольку вы объявляете обратный вызов, ваша функция setImmediate пытается разрешить второе обещание, вы, по сути, настроили условие гонки, когда лямбда заканчивается, перед запуском оператора консоли в функции.В любом случае, вы не получите желаемый ответ.

Попробуйте:

module.exports.handler = async (event, context) => {
  try {
    console.log('calling setImmediate...');
    var setImmediate = (function () {
      console.log('setImmediate callback invoked!');
      return('OK!!!!');
    });
    return setImmediate();
  } catch (e) {
    console.log('Failed!');
    console.log(e);
    return(e);
  }
};

Ваш код будет работать, если вы удалите асинхронное объявление, потому что старый синтаксис обратного вызова все еще поддерживается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...