gpt4 book ai didi

node.js - 如何使用 Lambda 函数对 Alexa Skill 应用程序进行异步 API 调用?

转载 作者:太空宇宙 更新时间:2023-11-03 23:19:05 24 4
gpt4 key购买 nike

我想从 Lambda 函数调用 api。我的处理程序由包含两个必需插槽的 intent 触发。因此,我事先不知道是否会返回 Dialog.Delegate 指令或 api 请求的响应。我如何在调用 intent 处理程序时 promise 这些返回值?

这是我的处理程序:

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();
});
}
},
};

这是我发出请求的辅助函数:

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 并在我的句柄函数前面放置一个“异步”?我对这一切都很陌生,所以我不知道这意味着什么,特别是考虑到我有两个不同的返回值,一个是直接返回值,另一个是延迟返回值。我该如何解决这个问题?

提前谢谢您。

最佳答案

正如您所怀疑的,您的处理程序代码在异步调用 http.request 之前完成,因此 Alexa SDK 不会从 handle 函数接收到返回值,并将向 Alexa 返回无效响应。

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

const https = require('https');

function httpGet(query, callback) {
var options = {
host: 'httpbin.org',
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。它产生

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

所以,关键是要等待 http get 返回,然后再向 Alexa 返回响应。为此,我建议修改您的 httpGet 函数以返回 promise ,而不是使用回调。

修改后的代码是这样的(我保留了你原来的代码作为注释)

const https = require('https');

async function httpGet(query) {
return new Promise( (resolve, reject) => {
var options = {
host: 'httpbin.org',
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

关于node.js - 如何使用 Lambda 函数对 Alexa Skill 应用程序进行异步 API 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51764274/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com