我正试图构建一个功能来从IoTHub获取数据并将数据通过GET发送到我的Web服务。
这就是我的职责:
var http = require('https');
module.exports = function (context, IoTHubMessages) {
IoTHubMessages.forEach(message => {
// context.log(`Processing message9: ${JSON.stringify(message)}`);
console.log(`what the what???`);
let url = `<my site in Azure>.azurewebsites.net`;
console.log(url);
let path = "/sensor/" + message.d1 + "/" + message.d2 + "/" + message.d3 + "/";
console.log(path);
var req = http.request({
host: url,
path: path,
method: 'GET'
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.on('end', function(e) {
console.log('finished with request');
});
req.end();
});
context.done();
};
日志如下:
2019-02-10T06:06:22.503 [Information] Executing 'Functions.IoTHub_EventHub1' (Reason='', Id=ea6109b0-5037-4f15-9efc-845222c6f404)
2019-02-10T06:06:22.512 [Information] Executed 'Functions.IoTHub_EventHub1' (Succeeded, Id=ea6109b0-5037-4f15-9efc-845222c6f404)
2019-02-10T06:06:22.786 [Information] Executing 'Functions.IoTHub_EventHub1' (Reason='', Id=f344c44f-a6ff-49b3-badb-58429b3476dc)
2019-02-10T06:06:22.796 [Information] Executed 'Functions.IoTHub_EventHub1' (Succeeded, Id=f344c44f-a6ff-49b3-badb-58429b3476dc)
如果我取消注释此行:
context.log(`Processing message9: ${JSON.stringify(message)}`);
然后,JSON数据显示在日志输出中。在执行和执行对之间,我看到:
2019-02-10T05:59:28.906 [Information] Processing message9: {"topic":"iot","d1":"200","d2":"200","d3":"200"}
console.log
消息我尝试用不同的引号引起来,看看Node是否首选一个。
有时重新启动功能时,我会在日志中看到类似这样的消息,但是由于日志中包含我的JSON字符串而忽略了它
2019-02-10T06:00:10.600 [Error] Executed 'Functions.IoTHub_EventHub1' (Failed, Id=2b3959cd-5014-4c50-89a3-77e37f2a890e)
Binding parameters to complex objects (such as 'Object') uses Json.NET serialization.
1. Bind the parameter type as 'string' instead of 'Object' to get the raw values and avoid JSON deserialization, or
2. Change the queue payload to be valid json. The JSON parser failed:
Unexpected character encountered while parsing value: T. Path '', line 0, position 0.
答案 0 :(得分:0)
这里的问题是forEach
循环不是在调用context.done
之前等待结果的循环
当@nelak在他的评论中指出这种情况发生时,azure函数将停止并且没有其他反应。
观察以下内容。我决定将http
库替换为简单的setTimeout
函数,但这大致相同。在下一个代码段中将说明代码所发生的情况,请注意console.log
的调用顺序。
const myFn = function (context, IoTHubMessages) {
IoTHubMessages.forEach(message => {
console.log('inside foreach!')
setTimeout(() => {
console.log('inside settimeout, this is when your request is answered!')
}, 1)
});
console.log('outside all!')
};
myFn(null, [0, 1])
如果您希望更改其他行为,则可以使用async-await
模式重写此代码,这似乎是同步的,但实际上是异步的。
var callIt = () => {
return new Promise((resolve) => {
setTimeout(() => {
console.log('inside settimeout!')
return resolve('ok')
}, 1)
})
}
var myFnAwait = async (context, IoTHubMessages) => {
for (i of IoTHubMessages){
console.log('before settimeout')
await callIt()
console.log('after timeout')
}
console.log('outside all!')
};
myFnAwait(null, [0, 1])