如何确保我的node.js处理程序在返回值之前完成api调用?

时间:2018-12-05 18:53:43

标签: node.js alexa-skill

我想确保我的处理程序从IBM Watson API接收到结果后返回“ speakoutput”。当我的代码调用IBM API时,它将直接跳转到“ return handlerInput.responseBuilder”,因为IBM API需要花费一些时间来分析输入文本。

我尝试了“ await”,“ promise”,但不适用于我的情况。 “ Await”和“ promise”可以确保我从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 :(得分:0)

将cb转换为一个Promise,并将Promise链作为您的handle函数返回。调用handle的任何人还必须使用.then()await

可以在https://github.com/alexa/skill-sample-nodejs-city-guide/blob/master/lambda/custom/index.js上找到aync handle()的示例

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