如何确保我的 node.js 处理程序在 returns 值之前完成 api 调用?
how to make sure my node.js handler finish an api call before it returns a value?
我想确保我的处理程序 returns "speakoutput" 在收到来自 IBM Watson API 的结果后。当我的代码调用IBMAPI时,它会直接跳转到"return handlerInput.responseBuilder",因为IBMAPI需要一些时间来分析输入的文本。
我尝试了 "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();
},
};
将 cb 转换为承诺,并将 return 承诺链作为您的 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());
}
}
);
}))
},
};
我想确保我的处理程序 returns "speakoutput" 在收到来自 IBM Watson API 的结果后。当我的代码调用IBMAPI时,它会直接跳转到"return handlerInput.responseBuilder",因为IBMAPI需要一些时间来分析输入的文本。
我尝试了 "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();
},
};
将 cb 转换为承诺,并将 return 承诺链作为您的 handle
函数。无论调用 handle
还必须使用 .then()
或 await
可在 https://github.com/alexa/skill-sample-nodejs-city-guide/blob/master/lambda/custom/index.js
找到 aynchandle()
的示例
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());
}
}
);
}))
},
};