我正在开发一个简单的IoT应用程序,该应用程序需要能够按需进行传感器测量。我使用的是无服务器架构,其中在静态站点上单击一个简单按钮即可触发Azure功能。此函数应在给定的IoT设备上调用直接方法,并将结果存储在Cosmos DB中。但是,当此函数执行(成功执行)时,invokeDeviceMethod的回调函数将永远不会执行。而是记录了context.log(“ Somehow I go here without a callback”“),该函数返回200成功。记录req.query.method和req.query.device的if语句内的行显示了这两个参数的期望值。我的设备永远不会收到调用该方法的请求,因此永远不会执行回调。为了从Azure函数调用给定方法,我缺少什么?将其作为函数运行并使用设备页面上的“直接方法”按钮从Azure门户调用直接方法时,我没有任何错误。预先感谢您的协助!
我的天蓝色功能代码在下面。
'use strict';
const https = require('https');
var Client = require('azure-iothub').Client
//var Protocol = require('azure-iot-device-mqtt').Mqtt;
var conn_str = "<CONNECTION_STRING>"
module.exports = async function (context, req) {
//context.log('JavaScript HTTP trigger function POSTMeasure processed a request.');
if (req.query.method && req.query.device) {
context.log("Direct Method Invocation! Calling "+req.query.method + " on " + req.query.device)
var methodParams = {
methodName: req.query.method,
payload: {},
connectTimeoutInSeconds: 15,
responseTimeoutInSeconds: 15
};
context.log(methodParams);
var client = Client.fromConnectionString(conn_str)
client.invokeDeviceMethod(req.query.device, methodParams, function(err, result) {
context.log("IN CALLBACK");
if (err) {
context.log("Direct method error: "+err.message);
context.res = {
status: 500, /* Defaults to 200 */
body: "Failed " + req.query.method + " on " + req.query.device
};
} else {
context.log("Successfully invoked the device to read dht11.");
console.log(JSON.stringify(result, null, 2));
context.res = {
// status: 200, /* Defaults to 200 */
body: "Suceeded " + req.query.method + " on " + req.query.device
};
}
});
context.log("Somehow I got here without a callback");
}
else {
context.res = {
status: 400,
body: "Please pass a method and device on the query string"
};
}
};
您的问题是,传递给invokeDeviceMethod的函数在调用完成之前不会执行。本质上,它是提供结果的回调函数。调用了invokeDeviceMethod函数后,JavaScript将执行下一行,即“我来了这里...”。您将需要修改代码,以等待invokeDeviceMethod完成并执行回调。现在我不是JavaScript程序员,但是您可以,例如,将调用包装在promise中,然后等待它。这样,您的函数将延迟到调用完成为止。如何执行此操作的原始示例:
// Target function to wrap in promise for demonstration purposes
function test(callback)
{
setTimeout(() => { callback(null, 'good') }, 4000);
}
// Wraps test in a promise
function testPromise()
{
var p = new Promise((resolve, reject) =>
{
test((err, result) =>
{
if (err)
{
reject(err);
}
else
{
resolve('good');
}
});
});
return p;
}
// Will not advance until the wrapped function has completed
testPromise()
.then((result) => { console.log(result) })
.catch(() => { console.log("failed"); } )