Node-RED e problemas de sincronia
O Node-RED pode ter alguns problemas de sincronia. Notei 2 tipos de problemas no dia-a-dia programando com ele.
O primeiro: o perigo em se usar callbacks dentro de um node Function.
Tanto o Node JS quanto o Javascript do browser fazem o uso intenso de callbacks.
Se dentro de algum node do Node-RED você chama uma função que usa callbacks, e deseja fazer mudanças no msg.payload, a primeira coisa que você pensaria em fazer seria isso
Imagine que voce precise usar alguma biblioteca que funcione através de callbacks. A alternativa mais simples e intuitiva será criar um node do tipo Function com algo assim:
console.log('inicio node');biblioteca.callbackDesejado((error, success) => {console.log('inicio callback'); if(error){console.log('Erro no callbackDesejado!')} var payloadProcessado = success.processarPayload(msg.payload); msg.payload = payloadProcessado;console.log('fim callback');});return msg;console.log('fim node');
Ao rodar esse código, perceberá que o msg.payload é o mesmo do início do node.
Isso acontece porque o return msg pode ser chamado ANTES MESMO da função bibloteca.callbackDesejado ser chamada.
Você perceberá a ordem das mensagens no console pode ser essa:
inicio nodeinicio callback fim node fim callback
O Node JS garante apenas que o inicio node será a primeira mensagem. A ordem das outras fica na vontade do computador.
Como solucionar isso? Use um método assíncrono para enviar mensagens.
Nestes casos é preciso usar a função assíncrona de envio de mensagens:
console.log('inicio node');biblioteca.callbackDesejado((error, success) => {console.log('inicio callback'); if(error){console.log('Erro no callbackDesejado!')} var payloadProcessado = success.processarPayload(msg.payload); msg.payload = payloadProcessado; node.send(msg); console.log('fim callback'); node.done();});console.log('fim node');
O segundo: o perigo em confiar na sequência de entrega das mensagens ao fazer um split.
Este post do blog do Node-RED explica melhor sobre isso:
https://nodered.org/blog/2019/08/16/going-async