[英]node.js Https call return undefined. Amazon AWS
編輯。 自第一篇文章以來,代碼現已更新:
“現在它的工作方式是這樣的:第一次運行pooltemp是不確定的。如果立即運行一次,我將得到pooltemp = 30(這是新的溫度)。這至少表明對Thingspeak的調用正在工作。如果運行它幾分鍾后再次出現,這是第一次未定義。似乎是AWS在函數完成后將值保留了一段時間。”
我對node.js完全陌生,但是具有以下代碼,這些代碼我大多是使用剪切和粘貼編寫的。 它正在Amazon AWS中運行,以響應Alexa調用。 我正在嘗試讀取Thingspeak通道以獲取池中的溫度。(URL返回一個帶有溫度的json。該通道由esp8266更新,該esp8266正在測量pooltemp並將其發布到該通道。不幸的是,我只得到了未定義的pooltemp我創建了函數getCall()來獲取Thinspeak的溫度。當我在handlerinput中使用變量pooltemp時,它是未定義的。其他一切工作正常。如果我在handlerinput中對pooltemp進行硬編碼,則得到想要的響應。代碼如下。非常感謝您的幫助。謝謝:
/* eslint-disable func-names */
/* eslint-disable no-console */
const Alexa = require('ask-sdk');
var https = require('https');
var pooltemp;
getCall();
//ThingSpeak Data Access
function getCall() {
var options = {
protocol: 'https:',
host: 'api.thingspeak.com',
path: '/channels/494722/feeds.json?api_key=9HILOGJ9P2HRDPNO&results=1',
method: 'GET'
};
var getReq = https.request(options, function(res) {
console.log("\nstatus code: ", res.statusCode);
var jsonData = '';
res.on('data', function(data) {
jsonData += data;
});
res.on('end', function() {
console.log('We have all the data');
var result = JSON.parse(jsonData);
console.log('data: ', result);
console.log('Pool temperature: ', result.feeds[0].field1);
// Save the latest pool temperature.
pooltemp = result.feeds[0].field1;
});
});
//end the request
getReq.end();
getReq.on('error', function(err) {
console.log("Error: ", err);
});
}
const GetNewFactHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest' ||
(request.type === 'IntentRequest' &&
request.intent.name === 'GetNewFactIntent');
},
handle(handlerInput) {
// var pooltemp = 22;
var factIndex;
const factArr = data;
if (pooltemp <= 15) {
factIndex = 0;
}
if (15 < pooltemp == pooltemp < 20) {
factIndex = 1;
}
if (20 <= pooltemp == pooltemp < 25) {
factIndex = 2;
}
if (pooltemp >= 25) {
factIndex = 3;
}
const randomFact = factArr[factIndex];
const speechOutput = 'Hold on a second, I will check for you.<break time="1s"/>Today it is ' + pooltemp + ' degrees in the pool. ' + randomFact;
return handlerInput.responseBuilder
.speak(speechOutput)
.withSimpleCard(SKILL_NAME, randomFact)
.getResponse();
},
};
const HelpHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' &&
request.intent.name === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak(HELP_MESSAGE)
.reprompt(HELP_REPROMPT)
.getResponse();
},
};
const ExitHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' &&
(request.intent.name === 'AMAZON.CancelIntent' ||
request.intent.name === 'AMAZON.StopIntent');
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak(STOP_MESSAGE)
.getResponse();
},
};
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionEndedRequest';
},
handle(handlerInput) {
console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);
return handlerInput.responseBuilder.getResponse();
},
};
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
console.log(`Error handled: ${error.message}`);
return handlerInput.responseBuilder
.speak('Sorry, an error occurred.')
.reprompt('Sorry, an error occurred.')
.getResponse();
},
};
const SKILL_NAME = 'Space Facts';
const GET_FACT_MESSAGE = 'Here\'s today temperature: ';
const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';
const data = [
'It is freezing cold. Swimming only for idiots',
'It is not for whimps, but you may swim. Do you dare go for it?',
'Wich is a nice temperature for a norwegian.',
'This is quite comfortable and a swim should be really nice ',
];
const skillBuilder = Alexa.SkillBuilders.standard();
exports.handler = skillBuilder
.addRequestHandlers(
GetNewFactHandler,
HelpHandler,
ExitHandler,
SessionEndedRequestHandler
)
.addErrorHandlers(ErrorHandler)
.lambda();
我已經檢查了一下,並對getCall()函數進行了一些修改,它現在應該可以工作:
function getCall() {
var options = {
protocol: 'https:',
host: 'api.thingspeak.com',
path: '/channels/494722/feeds.json?api_key=9HILOGJ9P2HRDPNO&results=1',
method: 'GET'
}
var getReq = https.request(options, function(res) {
console.log("\nstatus code: ", res.statusCode);
var jsonData = '';
res.on('data', function(data) {
jsonData += data;
});
res.on('end', function() {
console.log('We have all the data');
var result = JSON.parse(jsonData);
console.log('data: ', result);
console.log('Pool temperature: ', result.feeds[0].field1);
// Save the latest pool temperature.
poolTemp = result.feeds[0].field1;
});
});
//end the request
getReq.end();
getReq.on('error', function(err) {
console.log("Error: ", err);
});
}
getCall();
您也可以在腳本開始時嘗試以下操作:
getCall();
setInterval(getCall, 10000);
這將每10秒刷新池溫度。
當前,您的功能getCall()正在異步執行,因此pooltemp是未定義的。 由於成功執行getCall()函數之前的javascript asynchrouns性質,它將繼續到if條件
在這里,我使用javascript回調對getCall函數進行了更改。 同樣,在成功執行getCall函數之后,將在GetNewFactHandler handle()方法中執行其余條件。
/* eslint-disable func-names */
/* eslint-disable no-console */
const Alexa = require('ask-sdk');
var https = require('https');
//ThingSpeak Data Access
function getCall(callback) {
//initialize options values, the value of the method can be changed to POST to make https post calls
var options = {
protocol: 'https:',
host: 'api.thingspeak.com',
path: '/channels/494722/feeds.json?api_key=9HILOGJ9P2HRDPNO&results=1',
method: 'GET'
};
//making the https get call
https.request(options, function(res) {
console.log("\nstatus code: ", res.statusCode);
let data = ''
// A chunk of data has been recieved from request stream.
res.on('data', function(chunk) {
data += chunk;
});
// Once the whole response has been received, return response as callback
res.on('end', () => {
console.log('We have all the data');
var result = JSON.parse(data);
console.log('data: ', result);
console.log('Pool temperature: ', result.feeds[0].field1);
// Save the latest pool temperature.
const poolTemp = result.feeds[0].field1;
callback(null, poolTemp);
});
})
.on('error', function(err) {
callback(err);
});
}
const GetNewFactHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest' ||
(request.type === 'IntentRequest' &&
request.intent.name === 'GetNewFactIntent');
},
handle(handlerInput) {
getCall((err, pooltemp) => {
//Error handling implementation
if(err) {
console.log("Error: ", err);
}
//Validating condition after successful response from getCall
// var pooltemp = 22;
var factIndex;
const factArr = data;
if (pooltemp <= 15) {
factIndex = 0;
}
if (15 < pooltemp == pooltemp < 20) {
factIndex = 1;
}
if (20 <= pooltemp == pooltemp < 25) {
factIndex = 2;
}
if (pooltemp >= 25) {
factIndex = 3;
}
const randomFact = factArr[factIndex];
const speechOutput = 'Hold on a second, I will check for you.<break time="1s"/>Today it is ' + pooltemp + ' degrees in the pool. ' + randomFact;
return handlerInput.responseBuilder
.speak(speechOutput)
.withSimpleCard(SKILL_NAME, randomFact)
.getResponse();
}
},
};
const HelpHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' &&
request.intent.name === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak(HELP_MESSAGE)
.reprompt(HELP_REPROMPT)
.getResponse();
},
};
const ExitHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' &&
(request.intent.name === 'AMAZON.CancelIntent' ||
request.intent.name === 'AMAZON.StopIntent');
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak(STOP_MESSAGE)
.getResponse();
},
};
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionEndedRequest';
},
handle(handlerInput) {
console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);
return handlerInput.responseBuilder.getResponse();
},
};
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
console.log(`Error handled: ${error.message}`);
return handlerInput.responseBuilder
.speak('Sorry, an error occurred.')
.reprompt('Sorry, an error occurred.')
.getResponse();
},
};
const SKILL_NAME = 'Space Facts';
const GET_FACT_MESSAGE = 'Here\'s today temperature: ';
const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';
const data = [
'It is freezing cold. Swimming only for idiots',
'It is not for whimps, but you may swim. Do you dare go for it?',
'Wich is a nice temperature for a norwegian.',
'This is quite comfortable and a swim should be really nice ',
];
const skillBuilder = Alexa.SkillBuilders.standard();
exports.handler = skillBuilder
.addRequestHandlers(
GetNewFactHandler,
HelpHandler,
ExitHandler,
SessionEndedRequestHandler
)
.addErrorHandlers(ErrorHandler)
.lambda();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.