Функция Azure - js - работает неправильно, но в журналах нет ошибок - PullRequest
0 голосов
/ 10 февраля 2019

Я пытаюсь создать функцию для получения данных из моего IoTHub и отправки данных в мой веб-сервис через GET.

Это то, что я имею в своей функции:

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"}
  • Я не получаю свой запрос GET
  • Я не вижу сообщений console.log после начальной строки stringify
  • Я не вижу никаких ошибок.

Я пробовал разные кавычки, чтобы увидеть, предпочитает ли 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.

1 Ответ

0 голосов
/ 18 марта 2019

Проблема здесь в том, что цикл 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])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...