Лямбда-функция не возвращает ответ на умение Alexa - PullRequest
0 голосов
/ 10 октября 2018

У меня есть лямбда-функция для навыка Alexa, которая написана на Nodejs.Это делает HTTP-вызов к сервису и возвращает результат в Alexa Skill.Когда вызывается навык, вызывается лямбда и выполняется HTTP-вызов.Однако перед возвратом ответа HTTP возвращается лямбда, поэтому умение не получает ответа.

Ниже представлена ​​моя лямбда-функция

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

В журналах лямбды я вижулоги в getTop ().Но ответ лямбды возвращается до получения ответа HTTP-вызова.Я думал, что построение ответа в обратном вызове гарантирует, что ответ будет возвращен только после завершения HTTP-вызова.Но, похоже, это не так.Как это можно исправить?Любая помощь приветствуется.

1 Ответ

0 голосов
/ 11 октября 2018

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

Выполните функцию async и используйте , ожидайте , прежде чем позвонить в службу .. Вы также можетесделать это Обещания

...