我有一个用Nodejs编写的Alexa技能的Lambda函数。它对服务进行HTTP调用,并将输出返回给Alexa Skill。调用该技能时,将调用lambda,并进行HTTP调用。但是,在返回HTTP响应之前,lambda返回了,因此该技能没有得到答案。
下面是我的Lambda函数
var Alexa = require('ask-sdk');
var http = require('http');
var SKILL_NAME = 'Some Facts';
var GetNewFactHandler = {
canHandle(handlerInput) {
var request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest'
|| (request.type === 'IntentRequest'
&& request.intent.name === 'GetNewFactIntent');
},
handle(handlerInput) {
getTop("", (data)=>{
let speechOutput = "The result is " + data;
console.log("resp from lambda ", speechOutput)
var respSpeak = handlerInput.responseBuilder
.speak(speechOutput)
.withSimpleCard(SKILL_NAME, data)
.getResponse();
console.log("respSpeak ", respSpeak);
return respSpeak;
});
},
};
function getTop(query, callback) {
var options = {
host: 'somehost',
port: '8100',
path: '/top',
method: 'GET',
};
var req = http.request(options, res => {
res.setEncoding('utf8');
var responseString = "";
res.on('data', chunk => {
responseString = responseString + chunk;
});
res.on('end', () => {
console.log("********",JSON.parse(responseString).Name);
let respStr = JSON.parse(responseString).Name;
callback(respStr);
});
});
req.end();
}
在lambda日志中,我可以在getTop()中看到日志。但是,lambda的响应会在收到HTTP调用的响应之前返回。我以为在回调中构建响应将确保仅在HTTP调用完成后才返回响应。但这似乎并非如此。如何解决?任何帮助表示赞赏。
答案 0 :(得分:3)
Node.js在默认情况下为异步,这意味着在服务返回数据之前,将调用响应构建器。 调用客户资料api获取电话号码时,我遇到了类似的问题,我使用 async-await 这样解决了该问题
async handle(handlerInput) {
const { serviceClientFactory, responseBuilder } = handlerInput;
try {
const upsServiceClient = serviceClientFactory.getUpsServiceClient();
const profileMobileObject = await upsServiceClient.getProfileMobileNumber();
const profileMobile = profileMobileObject.phoneNumber;
const speechResponse = `Hello your mobile number is, ${profileMobile}</say-as>`;
const cardResponse = `Hello your mobile number is, ${profileMobile}`
return responseBuilder
.speak(speechResponse)
.withSimpleCard(APP_NAME, cardResponse)
.getResponse();
} catch (error) {
console.log(JSON.stringify(error));
if (error.statusCode == 403) {
return responseBuilder
.speak(messages.NOTIFY_MISSING_PERMISSIONS)
.withAskForPermissionsConsentCard([MOBILE_PERMISSION])
.getResponse();
}
console.log(JSON.stringify(error));
const response = responseBuilder.speak(messages.ERROR).getResponse();
return response;
}
},
启用功能异步,并在调用服务之前使用 await 。 您也可以通过 Promises