Как убедиться, что мой обработчик node.js завершает вызов API, прежде чем он возвращает значение? - PullRequest
0 голосов
/ 05 декабря 2018

Я хочу убедиться, что мой обработчик возвращает «voiceoutput» после получения результата от IBM Watson API.Когда мой код вызывает IBM API, он сразу переходит к «return handlerInput.responseBuilder», потому что IBM API требуется некоторое время для анализа входного текста.

Я пытался «ждать», «обещать», но в моем случае это не сработало.«Ожидание» и «обещание» могут обеспечить получение результата от API, но это никогда не помешает моему коду перейти на следующую строку, прежде чем он завершит вызов API.

Как мне решить эту проблему?

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    var speakoutput ='';


//IBM API HERE
    var NaturalLanguageUnderstandingV1 = require('watson-developer-cloud/natural-language-understanding/v1.js');
    var nlu = new NaturalLanguageUnderstandingV1({
      iam_apikey: 'my_api_key',
      version: '2018-04-05',
      url: 'https://gateway.watsonplatform.net/natural-language-    understanding/api/'
    });


//nlu.analyze takes a lot of time to process
    nlu.analyze(
      {
        html: 'Leonardo DiCaprio won Best Actor in a Leading Role for his performance', // Buffer or String
        features: {
          //concepts: {},
          'keywords': {},
          'relations': {},
          'sentiment': {
            'targets': [
              'in'
            ]
          }
        }
      },
      function(err, response) {
        if (err) {
          console.log('error:', err);
        } else {
          //console.log(JSON.stringify(response, null, 2));
          var temparray = [];
          for (i in response.keywords){
            speakoutput +=response.keywords[i].text;
            console.log(JSON.stringify(response.keywords[i].text, null, 2));
            temparray.push(response.keywords[i].text);
          }
          console.log(temparray);
        }
      }
    );


//my code will jump to this part before it finishes "nlu.analyze"
    return handlerInput.responseBuilder
      .speak(speakoutput)
      .reprompt('What do you want to know? you could search data for atm, course search, fed events,')
      .getResponse();
  },
};

1 Ответ

0 голосов
/ 05 декабря 2018

Конвертируйте cb в обещание и верните цепочку обещаний в качестве функции handle.Какие бы звонки handle не использовали также .then() или await

Пример aync handle() можно найти по адресу https://github.com/alexa/skill-sample-nodejs-city-guide/blob/master/lambda/custom/index.js

const GoOutHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;

        return request.type === 'IntentRequest' && request.intent.name === 'GoOutIntent';
    },
    handle(handlerInput) {
        return new Promise((resolve) => {
            getWeather((localTime, currentTemp, currentCondition) => {
                const speechOutput = `It is ${localTime
                } and the weather in ${data.city
                } is ${
                    currentTemp} and ${currentCondition}`;
                resolve(handlerInput.responseBuilder.speak(speechOutput).getResponse());
            });
        });
    },
};

Так что для вас:

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {



//nlu.analyze takes a lot of time to process
    return (new Promise(function(resolve,reject){ // convert cb to promise

        var speakoutput ='';


    //IBM API HERE
        var NaturalLanguageUnderstandingV1 = require('watson-developer-cloud/natural-language-understanding/v1.js');
        var nlu = new NaturalLanguageUnderstandingV1({
          iam_apikey: 'my_api_key',
          version: '2018-04-05',
          url: 'https://gateway.watsonplatform.net/natural-language-    understanding/api/'
        });

        nlu.analyze(
        {
            html: 'Leonardo DiCaprio won Best Actor in a Leading Role for his performance', // Buffer or String
            features: {
                //concepts: {},
                'keywords': {},
                'relations': {},
                'sentiment': {
                    'targets': [
                    'in'
                    ]
                }
            }
        },
        function(err, response) {
            if (err) {
                reject(err);
            } else {
                //console.log(JSON.stringify(response, null, 2));
                var temparray = [];
                for (i in response.keywords){
                    speakoutput +=response.keywords[i].text;
                    console.log(JSON.stringify(response.keywords[i].text, null, 2));
                    temparray.push(response.keywords[i].text);
                }
                console.log(temparray);
                resolve(handlerInput.responseBuilder
            .speak(speakoutput)
            .reprompt('What do you want to know? you could search data for atm, course search, fed events,')
            .getResponse());
            }
        }
        );
    }))
  },
};
...