Je suis nouveau dans les promesses, async / await, et Alexa / lambda, alors soyez indulgents avec moi.
Ma fonction est de retour avant que les données ne soient renvoyées. J'ai eu un problème similaire où j'obtenais une erreur, mais j'ai depuis modifié un peu ma fonction et donc posé une nouvelle question. Je n'obtiens plus d'erreur, mais mes données sont renvoyées en premier, puis la promesse s'exécute.
J'ai essayé de réécrire la promesse / fonction après avoir lu beaucoup, beaucoup de SO, forums de développeurs google et amazon. Rien ne semble fonctionner pour moi.
const IntentRequest = { canHandle(handlerInput) { return handlerInput.requestEnvelope.request.type === 'IntentRequest'; }, async handle(handlerInput) { const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput; let responseData, promise; checkAuthenticationStatus(handlerInput,function(json){ console.log('waited!') if(json.error) { return handlerInput.responseBuilder.speak(messages.NO_ACCESS).withSimpleCard('Unauthorized Request', messages.NO_ACCESS).getResponse(); } else if(json.noerror && json.noerror.okay == 'true'){ console.log('starting to get intent data') const url = new URL(json.noerror.okay.path); promise = new Promise((resolve, reject) => { console.log('start promise') return httpsGetIntent(handlerInput, url).then((resultData) => { console.log(resultData) responseData = resultData; resolve(responseData) console.log('inside promise, no error, prior to return data') }) }).then((result) => { console.log('result', result)}) return handlerInput.responseBuilder.speak('Test').getResponse(); } }); console.log('response data', responseData) let result = await promise; return result; }, };
Parmi mes nombreux console.logs () ajoutés pour le débogage, ils s'affichent comme suit: - 'données de réponse' - 'attendu!' - 'commencer à obtenir des données d'intention' - 'promesse de départ' - resultData - 'promesse intérieure, pas d'erreur, avant de renvoyer les données'
3 Réponses :
Bien que ce ne soit pas complètement détaillé (je dois aborder la partie de la gestion des erreurs), je voulais partager ma solution ici au cas où quelqu'un tomberait sur ce post et aurait besoin d'aide.
J'ai déplacé la promesse en dehors de la fonction checkAuthentication et renvoyé les données lors de son traitement. J'ai ensuite enchaîné la promesse avec .then () et lui ai transmis les données renvoyées, et j'ai invité Alexa à parler.
const IntentRequest = { canHandle(handlerInput) { return handlerInput.requestEnvelope.request.type === 'IntentRequest'; }, async handle(handlerInput) { const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput; let responseData, promise; return new Promise((resolve, reject) => { checkAuthenticationStatus(handlerInput, async function(json) { if (json.error) { return handlerInput.responseBuilder.speak(messages.NO_ACCESS).withSimpleCard('Unauthorized Request', messages.NO_ACCESS).getResponse(); } else if (json.noerror && json.noerror.okay == 'true') { const url = new URL(json.noerror.okay.path); let resultD = await httpsGetIntent(handlerInput, url, function(resultData) { if (resultData) { return resolve(resultData); } else { return resolve(handlerInput.responseBuilder.speak('False Test').getResponse()); } }) } }) }).then((data) => { return handlerInput.responseBuilder.speak(data.response.outputSpeech.text).getResponse(); }); }, };
httpsGetIntent ()
est un peu déroutant. D'une part, vous l'attendez
(indiquant qu'il renvoie Promise) tandis que d'autre part, il accepte un rappel. En règle générale, une fonction (ou tout appel particulier) présente un comportement ou un autre.
@ Roamer-1888 J'apprécie l'aide! Je ne comprends pas totalement async / await et je faisais référence à d'autres exemples d'Alexa
Presque_Ashleigh, basé sur votre propre réponse, quelques idées dans lesquelles j'ai:
httpsGetIntent ()
renvoie un Promsie qui fournit resultData
. checkAuthenticationStatus ()
en écrivant l'adaptateur checkAuthenticationStatusAsync ()
. .speak ()
dans les clauses finales .then ()
et .catch ()
. .title
, qui est utilisée dans le .catch ()
final en tant que cardTitle. Toute erreur non décorée sera par défaut "Désolé" (ou ce que vous voulez). // in a suitable scope ... function checkAuthenticationStatusAsync(handlerInput) { return new Promise((resolve, reject) { checkAuthenticationStatus(handlerInput, (json) => { if (json.error || !json.noerror || json.noerror.okay !== 'true') { let err = new Error(messages.NO_ACCESS); // or maybe a separate error message per error case? err.title = 'Unauthorized Request'; reject(err); } else { resolve(json); } }); }); } // ... and ... const IntentRequest = { canHandle(handlerInput) { return handlerInput.requestEnvelope.request.type === 'IntentRequest'; }, handle(handlerInput) { return checkAuthenticationStatusAsync(handlerInput) .then((json) => httpsGetIntent(handlerInput, new URL(json.noerror.okay.path))) .then((resultData) => { if (resultData) { // success path ends here return handlerInput.responseBuilder.speak(resultData.response.outputSpeech.text).getResponse(); } else { throw new Error('No result data returned'); // throws to the .catch() below } }) .catch(err => { // all errors end up here. return handlerInput.responseBuilder.speak(err.message).withSimpleCard(err.title || 'Sorry', err.message).getResponse(); throw err; // to keep handle's caller informed }); }, };
Notez que c'est une façon, pas nécessairement la façon, d'écrire le code. N'hésitez pas à chercher des idées.
Comme écrit,
return handlerInput.responseBuilder.speak ('Test'). GetResponse ();
n'est pas dans un callback .then, malgré l'indentation qui le fait apparaître autrement. Il y a aussi d'autres choses à corriger.Merci @ Roamer-1888! En fait, j'ai résolu ce problème hier soir et je suis sur le point de publier ma réponse.