如何使用Lambda函数对Alexa Skill应用程序进行异步api调用?

编程入门 行业动态 更新时间:2024-10-08 01:33:22
本文介绍了如何使用Lambda函数对Alexa Skill应用程序进行异步api调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我想从Lambda函数调用api。我的处理程序由包含两个必需插槽的意图触发。因此,我事先不知道我是否要返回 Dialog.Delegate 指令或我对api请求的响应。

I want to call an api from a Lambda function. My handler is triggered by an intent which includes two required slots. Therefore I don't know in advance whether I will be returning a Dialog.Delegate directive or my response from the api request. How do I promise these return values by the time the intent handler is called?

这是我的处理程序:

const FlightDelayIntentHandler = { canHandle(handlerInput) { return handlerInput.requestEnvelope.request.type === 'IntentRequest' && handlerInput.requestEnvelope.request.intent.name === 'MyIntent'; }, handle(handlerInput) { const request = handlerInput.requestEnvelope.request; if (request.dialogState != "COMPLETED"){ return handlerInput.responseBuilder .addDelegateDirective(request.intent) .getResponse(); } else { // Make asynchronous api call, wait for the response and return. var query = 'someTestStringFromASlot'; httpGet(query, (result) => { return handlerInput.responseBuilder .speak('I found something' + result) .reprompt('test') .withSimpleCard('Hello World', 'test') .getResponse(); }); } }, };

这是我的帮助程序,它发出请求:

This is my helper function which makes the request:

const https = require('https'); function httpGet(query, callback) { var options = { host: 'myHost', path: 'someTestPath/' + query, method: 'GET', headers: { 'theId': 'myId' } }; var req = https.request(options, res => { res.setEncoding('utf8'); var responseString = ""; //accept incoming data asynchronously res.on('data', chunk => { responseString = responseString + chunk; }); //return the data when streaming is complete res.on('end', () => { console.log('==> Answering: '); callback(responseString); }); }); req.end(); }

所以我怀疑我将不得不使用Promise并在其中添加异步我的句柄功能的前面?我对这一切都很陌生,所以我不知道这意味着什么,尤其是考虑到我有两个不同的返回值,一个是直接的,另一个是延迟的。我该怎么解决?

So I suspect I will have to use promises and put an "async" in front of my handle function? I am very new to all of this so I don't know the implications of this, especially considering the fact that I have two different return values, one directly and the other one delayed. How would I solve this?

谢谢。

推荐答案

您怀疑,您的处理程序代码在异步调用http.request之前已经完成,因此Alexa SDK没有从 handle 函数接收任何返回值,并且将返回无效响应

As you suspected, your handler code is finishing before the asynchronous call to http.request, hence the Alexa SDK receives no return value from the handle function and will return an invalid response to Alexa.

我稍微修改了您的代码,以在笔记本电脑上本地运行它来说明问题:

I slightly modified your code to run it locally on a laptop to illustrate the issue :

const https = require('https'); function httpGet(query, callback) { var options = { host: 'httpbin', path: 'anything/' + query, method: 'GET', headers: { 'theId': 'myId' } }; var req = https.request(options, res => { res.setEncoding('utf8'); var responseString = ""; //accept incoming data asynchronously res.on('data', chunk => { responseString = responseString + chunk; }); //return the data when streaming is complete res.on('end', () => { console.log('==> Answering: '); callback(responseString); }); }); req.end(); } function FlightDelayIntentHandler() { // canHandle(handlerInput) { // return handlerInput.requestEnvelope.request.type === 'IntentRequest' // && handlerInput.requestEnvelope.request.intent.name === 'MyIntent'; // }, // handle(handlerInput) { // const request = handlerInput.requestEnvelope.request; // if (request.dialogState != "COMPLETED"){ // return handlerInput.responseBuilder // .addDelegateDirective(request.intent) // .getResponse(); // } else { // Make asynchronous api call, wait for the response and return. var query = 'someTestStringFromASlot'; httpGet(query, (result) => { console.log("I found something " + result); // return handlerInput.responseBuilder // .speak('I found something' + result) // .reprompt('test') // .withSimpleCard('Hello World', 'test') // .getResponse(); }); console.log("end of function reached before httpGet will return"); // } // } } FlightDelayIntentHandler();

要运行此代码,请不要忘记 npm install http ,然后是 node test.js 。它产生

To run this code, do not forget npm install http , then node test.js. It produces

stormacq:~/Desktop/temp $ node test.js end of function reached before httpGet will return ==> Answering: I found something { "args": {}, "data": "", ...

所以,关键是要等 http get 返回之后再返回对Alexa的响应。为此,我建议修改您的 httpGet 函数以使用回调返回承诺。

So, the key is to wait for http get to return before to return a response to Alexa. For that, I propose to modify your httpGet function to return a promise instead using callbacks.

修改后的代码就像这个(我保留了您的原始代码作为注释)

Modified code is like this (I kept your original code as comment)

const https = require('https'); async function httpGet(query) { return new Promise( (resolve, reject) => { var options = { host: 'httpbin', path: 'anything/' + query, method: 'GET', headers: { 'theId': 'myId' } }; var req = https.request(options, res => { res.setEncoding('utf8'); var responseString = ""; //accept incoming data asynchronously res.on('data', chunk => { responseString = responseString + chunk; }); //return the data when streaming is complete res.on('end', () => { console.log('==> Answering: '); resolve(responseString); }); //should handle errors as well and call reject()! }); req.end(); }); } async function FlightDelayIntentHandler() { // canHandle(handlerInput) { // return handlerInput.requestEnvelope.request.type === 'IntentRequest' // && handlerInput.requestEnvelope.request.intent.name === 'MyIntent'; // }, // handle(handlerInput) { // const request = handlerInput.requestEnvelope.request; // if (request.dialogState != "COMPLETED"){ // return handlerInput.responseBuilder // .addDelegateDirective(request.intent) // .getResponse(); // } else { // Make asynchronous api call, wait for the response and return. var query = 'someTestStringFromASlot'; var result = await httpGet(query); console.log("I found something " + result); // return handlerInput.responseBuilder // .speak('I found something' + result) // .reprompt('test') // .withSimpleCard('Hello World', 'test') // .getResponse(); //}); console.log("end of function reached AFTER httpGet will return"); // } // } } FlightDelayIntentHandler();

运行此代码将产生:

stormacq:~/Desktop/temp $ node test.js ==> Answering: I found something{ "args": {}, "data": "", ... end of function reached AFTER httpGet will return

更多推荐

如何使用Lambda函数对Alexa Skill应用程序进行异步api调用?

本文发布于:2023-11-28 04:13:34,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1640911.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何使用   应用程序   函数   Alexa   Lambda

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!