Appel simple à ec2 Description des groupes de sécurité et renvoi de l'ID du groupe de sécurité. En utilisant Async / await, mais lors de la journalisation de la valeur de retour, je ne suis pas défini. J'admets pleinement que je viens de Python et j'ai fait de mon mieux pour envelopper mon cerveau autour des appels asynchrones. Je pensais l'avoir cloué, mais il me manque évidemment quelque chose.
'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.log(sgId)}); }
"sgId" devrait renvoyer l'ID du groupe de sécurité. Il s'imprime correctement dans la fonction d'origine avant le retour.
3 Réponses :
Comme je l'ai dit dans le commentaire, il y a de fortes chances que describeSecurityGroups
ne renvoie pas de Promise
. Essayez plutôt de le transformer explicitement en une promesse:
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
Remarque: vous pouvez supprimer le mot-clé else
Vous avez raison en ce que mon ec2.describeSecurityGroups
ne renvoie pas de promesse, il renvoie une requête AWS . Merci! Cela m'a conduit sur la bonne voie pour obtenir le code dont j'avais besoin.
En général, s'il s'agit d'un appel asynchrone, vous voulez le gérer de la même manière sans utiliser de rappel
// 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.log('handle error'); // throw error; } }); }; // MAIN FUNCTION exports.handler = (event, context) => { getSgIdFromEvent(event) .then(sgId => { console.log(sgId) }); }
cependant s'il ne prend pas en charge async, vous utilisez simplement le rappel pour gérer le a renvoyé des données ou une erreur sans utiliser la fonction async.Cependant, en lisant les documents AWS, vous pouvez constater que la fonction ec2.describeSecurityGroups () renvoie un Requête AWS qui a une méthode promise () qui doit être invoqué pour envoyer la demande et obtenir une promesse retournée. Notez que le try catch ici n'est pas nécessaire mais qu'il est bon d'avoir une erreur au cours du processus.
Êtes-vous sûr que la méthode renvoie une promesse? Je ne connais pas assez bien AWS
@ CristianTraìna Je n'étais pas sûr non plus, mais maintenant que j'avais plus de temps, je viens de lire leurs documents AWS, j'ai mis à jour la réponse, lisez la section du bas pour voir ce qu'elle retourne et comment en obtenir une promesse.
Voici le code qui a fonctionné en utilisant async / await
. Grâce à @Cristian Traina, j'ai réalisé que ec2.describeSecurityGroups
ne retournait pas de promesse, il renvoyait un AWS.Event
.
// Get Security Group ID From Event const getSgIdFromEvent = async (event) => { console.log('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.log(`Getting SG Ingress rules for ${sgId}`) var params = { GroupIds: [ sgId]}; try{ const ingressRules = await ec2.describeSecurityGroups(params).promise(); return ingressRules; } catch (error) { console.log("Something went wrong getting Ingress Ruls"); } }; // MAIN FUNCTION exports.handler = (event, context) => { getSgIdFromEvent(event) .then(sgId => {return getSgIngressRules(sgId);}) .then(ingressRules => {console.log(ingressRules);}); }
J'ai soumis ceci comme réponse maintenant puisque la fonction getSgIdFromEvent
que j'ai, ne fait que 8 lignes et utilise toujours async / await
comme je le souhaitais.
Ce qui me manquait était le .promise ()
à la fin de la fonction et le retour de cette promesse.
Merci pour toutes les réponses!
Ici, vous utilisez une fonction asynchrone, mais l'attente a toujours un rappel qui n'est pas ce qu'il est censé être, async est utilisé pour remplacer les rappels.Voir ma réponse mise à jour ci-dessus pour une meilleure solution où le rappel est désactivé.
vérifiez la partie où vous passez une fonction en tant que rappel dans describeSecurityGroups pour obtenir une erreur, la réponse à la mienne n'est pas nécessaire et ce n'est pas du tout nécessaire lorsque vous utilisez la fonction asynchrone
Je comprends ce que vous dites maintenant. Merci!
Heureux que vous ayez fait :)
Êtes-vous sûr que la méthode
describeSecurityGroups
renvoie une promesse? Habituellement, les fonctions qui acceptent les rappels n'utilisent pas Promise, car ce sont deux façons différentes de résoudre le même problème. Alors peut-être que vous devez promettre le rappelVoici un bel article qui décrit cela en détails: medium.freecodecamp.org/...
J'ai également remarqué que vous essayiez de revenir dans un rappel. JAMAIS retourne dans un callback en espérant que la sortie sera disponible à l'extérieur