从Azure函数调用直接方法和处理结果

问题描述 投票:0回答:1

我正在开发一个简单的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"
        };
    }
};
azure azure-functions azure-iot-hub
1个回答
0
投票

您的问题是,传递给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"); } )

© www.soinside.com 2019 - 2024. All rights reserved.