Node.js Lambda Async return Undefined

Простой вызов ec2 с описанием групп безопасности и возвращением идентификатора группы безопасности. Используя Async / await, но при регистрации возвращаемого значения я получаю undefined. Я полностью признаю, что исхожу из Python, и я изо всех сил старался понять, что такое асинхронные вызовы. Я думал, что у меня это получилось, но мне явно чего-то не хватает.

'use strict';

// Load Modules
const AWS = require('aws-sdk')

//Set the region
AWS.config.update({region: 'us-west-2'});

// Call AWS Resources
const ec2 = new AWS.EC2();

// Get Security Group ID From Event
const getSgIdFromEvent = async (event) => {
  var ec2params = { Filters: [{Name: 'tag:t_whitelist',Values[event['site']]}]};
  await ec2.describeSecurityGroups(ec2params, function (err, response) {
    if (err) {return console.error(err.message)}
    else {
      var sgId = response.SecurityGroups[0].GroupId;
      return sgId;
    };
  });
 };
// MAIN FUNCTION
exports.handler = (event, context) => {
  getSgIdFromEvent(event)
   .then(sgId => {console.info(sgId)});
}

«sgId» должен возвращать идентификатор группы безопасности. Он отлично распечатывает исходную функцию перед возвратом.

Вы уверены, что метод describeSecurityGroups возвращает обещание? Обычно функции, которые принимают обратные вызовы, затем не используют Promise, потому что это два разных способа решения одной и той же проблемы. Так что, возможно, вам нужно пообещать обратный вызов

Cristian Traìna 01.01.2019 01:14

Вот хорошая статья, в которой это подробно описано: medium.freecodecamp.org/…

ebu_sho 01.01.2019 01:19

Я также заметил, что вы пытались вернуться в обратном вызове. НИКОГДА возвращается внутри обратных вызовов, ожидая, что вывод будет доступен за пределами

Cristian Traìna 01.01.2019 01:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
1 005
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Как я сказал в комментарии, есть вероятность, что describeSecurityGroups не возвращает Promise. Попробуйте вместо этого явно преобразовать его в обещание:

const promiseResponse = await new Promise((res, rej) => {
  ec2.describeSecurityGroups(ec2params, function (err, response) {
    if (err) {return rej(err.message)}
    else {
      var sgId = response.SecurityGroups[0].GroupId;
      res(sgId);
    };
  })
});

// promiseResponse is now equal to sgId inside the callback
return promiseResponse; // this will work because the function is async

Примечание. Вы можете удалить ключевое слово else.

Вы правы в том, что мой ec2.describeSecurityGroups не возвращает обещание, он возвращает AWS Запрос. Спасибо! Это привело меня к правильному пути к получению кода, который мне был нужен.

mbspark 01.01.2019 17:10
Ответ принят как подходящий

Обычно, если это асинхронный вызов, вы хотите, чтобы вы обрабатывали его аналогично этому способу без использования обратного вызова

// Load Modules
const AWS = require('aws-sdk')

//Set the region
AWS.config.update({ region: 'us-west-2' });

// Call AWS Resources
const ec2 = new AWS.EC2();

// Get Security Group ID From Event
const getSgIdFromEvent = async (event) => {
    var ec2params = { Filters: [{ Name: 'tag:t_whitelist', Values[event['site']]}] };
    try {
        const securityGroupsDesc = await ec2.describeSecurityGroups(ec2params).promise();
        const sgId = securityGroupsDesc.SecurityGroups[0].GroupId;
        //do something with the returned result
        return sgId;
    }
    catch (error) {
        console.info('handle error');
        // throw error;
    }
});
 };
// MAIN FUNCTION
exports.handler = (event, context) => {
    getSgIdFromEvent(event)
        .then(sgId => { console.info(sgId) });
}

однако, если он не поддерживает асинхронность, вы просто используете обратный вызов для обработки возвращенных данных или ошибки без использования функции async. Однако при чтении документации AWS вы можете обнаружить, что функция ec2.describeSecurityGroups () возвращает AWS Запрос у которого есть метод обещать(), который необходимо вызвать, чтобы отправить запрос и получить возвращенное обещание. Обратите внимание, что здесь не требуется try catch, но его полезно иметь в случае возникновения ошибки во время процесса.

Вы уверены, что метод возвращает обещание? Я недостаточно хорошо знаю AWS

Cristian Traìna 01.01.2019 18:12

@ CristianTraìna Я тоже не был уверен, но теперь, когда у меня было больше времени, я просто прочитал их документацию AWS, я обновил ответ, прочитайте нижний раздел, чтобы узнать, что он возвращает и как получить от него обещание.

Dasith 02.01.2019 01:29

Вот код, который работал с async / await. Благодаря @Cristian Traina я понял, что ec2.describeSecurityGroups не возвращал обещание, он возвращал AWS.Event.

// Get Security Group ID From Event
const getSgIdFromEvent = async (event) => {
  console.info('Getting Security Group ID')
  var params = { Filters: [{Name: 'tag:t_whitelist', Values 
   [event['site']]}]};
  const describeSG = await ec2.describeSecurityGroups(params).promise();
  return describeSG.SecurityGroups[0].GroupId;
 };

// Get Ingress Rules from Security Group
const getSgIngressRules = async (sgId) => {
  console.info(`Getting SG Ingress rules for ${sgId}`)
  var params = { GroupIds: [ sgId]};
  try{
    const ingressRules = await ec2.describeSecurityGroups(params).promise();
    return ingressRules;
  }
  catch (error) {
    console.info("Something went wrong getting Ingress Ruls");
  }
 };

// MAIN FUNCTION
exports.handler = (event, context) => {
  getSgIdFromEvent(event)
  .then(sgId => {return getSgIngressRules(sgId);}) 
  .then(ingressRules => {console.info(ingressRules);});
}

Я представил это как ответ сейчас, поскольку функция getSgIdFromEvent, которая у меня есть, состоит всего из 8 строк и все еще использую async/await, как я и хотел.

Чего мне не хватало, так это .promise() в конце функции, возвращающего это обещание.

Спасибо за все ответы!

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

Dasith 02.01.2019 01:39

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

Dasith 02.01.2019 17:15

Я понимаю, о чем вы сейчас говорите. Спасибо!

mbspark 02.01.2019 18:02

Рад, что ты сделал :)

Dasith 02.01.2019 19:55

Другие вопросы по теме