Node-RED:如何在所有输入完成后触发函数一次性输出数据?
问题描述
我编写了如下Node-RED节点代码:
function socketIoEmit(n) { RED.nodes.createNode(this, n); const node = this; this.instance = RED.nodes.getNode(n.instance).instance; const optionsList = []; node.on("input", (msg) => { optionsList.push(msg); }); // I want to output this optionsList }
该节点用于收集OPC UA Item节点的输入数据并存入optionsList,我希望在所有输入完成后一次性输出这个optionsList。目前输入的OPC UA Item节点数量不固定(可能1到100个),因此无法确定何时将数据发送至服务器,请问是否存在类似node.on("afterAllInputs")或node.on("end")的触发方式?
解决方案
Node-RED原生并没有afterAllInputs这类专门监听所有输入完成的事件,你可以通过以下几种方式实现需求:
通过标记消息触发汇总
在所有OPC UA Item节点的输出消息中,给最后一个完成的消息添加特殊标记(比如msg.isLast = true),然后在自定义节点里判断:node.on("input", (msg) => { optionsList.push(msg); // 检查是否是最后一条消息 if (msg.isLast) { node.send({ payload: optionsList }); // 清空列表,准备下一轮收集 optionsList.length = 0; } });这种方式需要你能控制OPC UA节点的输出标记,适合可以提前确定最后一个节点的场景。
使用定时器做批量汇总
设置一个定时器,当收到第一条消息后启动,在指定时间内没有新消息进来时,就触发输出。这种方式适合输入间隔有规律的场景:let timer = null; node.on("input", (msg) => { optionsList.push(msg); // 每次收到消息就重置定时器 if (timer) clearTimeout(timer); timer = setTimeout(() => { node.send({ payload: optionsList }); optionsList.length = 0; timer = null; }, 1000); // 1秒无新消息则触发,可根据实际调整 });通过外部信号触发
添加一个额外的输入端口,专门接收"汇总触发"信号。当所有OPC UA节点数据收集完成后,发送一个触发消息到这个端口,节点收到后输出汇总列表:// 初始化时设置多输入端口 RED.nodes.createNode(this, n); const node = this; this.instance = RED.nodes.getNode(n.instance).instance; const optionsList = []; // 监听数据输入端口 node.on("input", (msg) => { // 判断是数据消息还是触发消息,比如通过msg.topic区分 if (msg.topic !== "trigger") { optionsList.push(msg); } else { node.send({ payload: optionsList }); optionsList.length = 0; } });这种方式灵活性最高,完全由外部控制汇总时机。
内容的提问来源于stack exchange,提问作者Jantoma21
相关产品推荐
相关产品推荐

