SerialPort.js每次请求响应行数递增问题求助
使用SerialPort.js向串口发送命令时,每次发送相同命令(如V),返回的响应行数都会比上一次多一行,调用port.flush()方法也无法解决该问题。
相关代码及响应记录
发送命令代码
port.write(data.command + "\n"); console.log("command =>", data.command); const parser = port.pipe(new ReadlineParser({ delimiter: "\r\n" })); parser.on("data", (line) => { console.log(line); });
命令与响应记录
command => V
v,4.0.0.0,8f834655363231164c343132
command => V
v,4.0.0.0,8f834655363231164c343132
v,4.0.0.0,8f834655363231164c343132
command => V
v,4.0.0.0,8f834655363231164c343132
v,4.0.0.0,8f834655363231164c343132
v,4.0.0.0,8f834655363231164c343132
command => V
v,4.0.0.0,8f834655363231164c343132
v,4.0.0.0,8f834655363231164c343132
v,4.0.0.0,8f834655363231164c343132
v,4.0.0.0,8f834655363231164c343132
尝试flush的代码
port.flush((error) => { console.log("port flushed") const parser = port.pipe(new ReadlineParser({ delimiter: '\r' })) parser.on('data', line => { console.log(line) }) })
问题根源
每次发送命令时,都重复创建了ReadlineParser实例并绑定data事件。每多发送一次命令,就会多一个事件监听器,串口返回的响应会被所有已绑定的监听器各自触发一次,导致响应行数随发送次数递增。port.flush()只能清空串口缓冲区,无法解决重复监听的问题。
解决方案
将ReadlineParser的创建和data事件监听移到串口初始化完成后仅执行一次,不要每次发送命令都重复创建。
修正后的代码示例
// 串口初始化完成后执行一次,不要放在发送命令的逻辑里 const parser = port.pipe(new ReadlineParser({ delimiter: "\r\n" })); parser.on("data", (line) => { console.log(line); }); // 单独封装发送命令的函数 function sendSerialCommand(command) { port.write(command + "\n"); console.log("command =>", command); } // 调用发送命令 sendSerialCommand("V");
如果需要在每次发送命令后仅接收一次响应,可以使用一次性事件监听:
function sendSerialCommandOnce(command) { port.write(command + "\n"); console.log("command =>", command); const parser = port.pipe(new ReadlineParser({ delimiter: "\r\n" })); // 使用once绑定,只触发一次后自动移除监听 parser.once("data", (line) => { console.log(line); // 可选:解除pipe关联 parser.unpipe(); }); }
内容的提问来源于stack exchange,提问作者Alexandr Fridrik

