我正在尝试在我的Alexa技能中调用第三方API,并且我在CloudWatch日志中收到了“会话以原因结束:错误”。问题似乎出现在我的NumberIntentHandler或我的httpGet函数中,但我不知道在哪里。
更新代码
- 被解雇的处理程序 -
const NumberIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'NumberIntent';
},
handle(handlerInput) {
let slotNum = handlerInput.requestEnvelope.request.intent.slots.number.value;
//var myRequest = parseInt(slotNum);
const myRequest = parseInt(slotNum);
console.log('NumberIntentHandler myRequest: ', myRequest);
var options = `http://numbersapi.com/${myRequest}`;
console.log('NumberIntentHandler options: ', options);
// Use the async function
const myResult = httpGet(options);
console.log("sent : " + options);
console.log("received : " + myResult);
const speechText = myResult;
console.log('speechText: ', speechText); // Print the speechText */
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('Here is your fact: ', speechText)
.getResponse();
},
};
- 从处理程序调用的函数 -
async function httpGet(options) {
// return new pending promise
console.log(`~~~~~~~~~ httpGet ~~~~~~~~~`);
console.log(`~~~~~${JSON.stringify(options)}~~~~~`);
return new Promise((resolve, reject) => {
const request = http.get(options, (response) => {
// handle http errors
if (response < 200 || response > 299) {
reject(new Error('Failed to load page, status code: ' + response));
}// temporary data holder
const body = [];
// on every content chunk, push it to the data array
response.on('data', (chunk) => body.push(chunk));
// we are done, resolve promise with those joined chunks
response.on('end', () => resolve(body.join('')));
console.log('body: ', body[0]);
});
// handle connection errors of the request
request.on('error', (err) => reject(err));
request.end();
});
}
更新的代码 - 消除异步/等待/承诺
- 处理程序 -
const NumberIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'NumberIntent';
},
handle(handlerInput) {
let slotNum = handlerInput.requestEnvelope.request.intent.slots.number.value;
//var myRequest = parseInt(slotNum);
const myRequest = parseInt(slotNum);
console.log('NumberIntentHandler myRequest: ', myRequest);
var options = `http://numbersapi.com/${myRequest}`;
console.log('NumberIntentHandler options: ', options);
// Use the async function
//const myResult = httpGet(options);
const myResult = httpGet(options, res => {
console.log("sent : " + options);
console.log("received : " + myResult);
const speechText = myResult;
console.log('speechText: ', speechText); // Print the speechText */
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('Here is your fact: ', speechText)
.getResponse();
});
},
};
- 功能 -
function httpGet(options, cb) {
http.get(options, res => {
console.log(`~~~~~${JSON.stringify(options)}~~~~~`);
// simplified version without error handling
let output = [];
res.on('data', d => output.push(d)); // or concat to a string instead?
res.on('end', () => cb(output));
console.log('output: ', output[0]);
});
}
答案 0 :(得分:1)
我相信您需要在httpGet中使用您的回复来解决问题。
作为旁注(与你的问题无关) - 我可以推荐使用request-promise,它在http周围实现了一个非常好的promise api,并且在这种情况下会简化你的代码。 (我知道我知道,async / await是新的有趣工具,但在这种情况下,我会选择“更简单”:))。
另外,如果我没记错的话,只用一个参数调用http.get的回调。
更改后编辑:
你可以摆脱承诺和异步来简化你的代码。 只是关于async / await的注释 - 如果等待 ed表达式不是一个promise,那么它会自动转换为一个。在您当前的代码中,您需要像承诺一样使用它(例如链式.then())或等待它。
无论如何,这是一个只使用回调的例子:
function httpGet(options, cb) {
http.get(options, res => {
// simplified version without error handling
let output = [];
res.on('data', d => output.push(d)); // or concat to a string instead?
res.on('end', () => cb(output));
});
}
httpGet(options, res => {
// building the alexa response, all your intent handler code that needs the response from your request
})