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

编程入门 行业动态 更新时间:2024-10-07 23:24:40
本文介绍了如何使用 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(); }

所以我怀疑我将不得不使用承诺并在我的句柄函数前放置一个异步"?我对这一切都很陌生,所以我不知道这意味着什么,特别是考虑到我有两个不同的返回值,一个是直接的,另一个是延迟的.我该如何解决这个问题?

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 函数,并将向 Alexa 返回无效响应.

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

发布评论

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

>www.elefans.com

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