node.js多个SerialPorts

我正在使用用于nodejs的SerialPorts模块,并且需要能够打开,写入和读取可变数量的串行端口。

所以我正在做的是先为serialPort实例创build一个数组对象,然后在一个循环中处理它们:

var serialport = require("serialport"); var SerialPort = serialport.SerialPort; // localize object constructor var devs = ["/dev/tty.SerialPort","/dev/tty.HHW-SPP-1800-2-DevB"]; var ports = []; for (var i = 0; i < devs.length; i++) { console.log(devs[i]); var port = new SerialPort(devs[i],{ baudrate:9600, parser: serialport.parsers.readline("\n") }); ports.push(port); } 

然后我有另一个函数,我周期性地调用来从端口读取/写入:

 function minute(){ for (var i = 0; i < ports.length; i++) { console.log(i); ports[i].on("open", function (path) { console.log('opened'); ports[i].write("Helo World\n", function(err,res) { if(err) console.log('err ' + err); console.log('results ' + res); }); ports[i].on("data", function (data) { console.log("here: "+data); }); }); } } 

问题是执行minute()函数,但是它不会尝试打开或读取/写入端口。

我究竟做错了什么 ?? 有没有更好的方式做到这一点?

玩这里有一些误解。

首先,你不需要定期轮询你的端口。 Nodejs使用一个事件循环(或多或less)来处理IO,并且会为你进行轮询。 所以你所要做的就是设置open事件的callback,每个端口一次。 在你的代码中,每当minute()被调用时,看起来你正在读callback函数。 这是没有必要的。

其次,JavaScript没有variables的块范围。 相反,您无意中创build了一个闭包,而您的代码出错了。 在下面的块中:

 for (var i = 0; i < ports.length; i++) { ports[i].on("open", function (path) { ports[i].write("Helo World\n", function(err,res) { if(err) console.log('err ' + err); console.log('results ' + res); }); ports[i].on("data", function (data) { console.log("here: "+data); }); }); } 

当您调用ports.on的callback函数时, ports[i].writeports[i].on("data")中的i的值不是设置callback函数时的i值,正如您期待的那样。 相反,因为您创build了一个闭包,所以在执行callback之前, i的值不会被绑定(设置)。 在这个例子中,你的callback中的每个人, i将被设置为ports.length ,这是i的最后一个评估值

我已经创build了一个演示你的for循环的问题 。

解决这个问题的一种方法是使用匿名方法,并将值绑定到一个新的局部variables。 在下面的代码中, (function(index){})(i); 立即执行,并将值index绑定到i的适当值。

 ports[i].on("open", function (path) { (function(index) { ports[index].write("Helo World\n", function(err,res) { if(err) console.log('err ' + err); console.log('results ' + res); }); ports[index].on("data", function (data) { console.log("here: "+data); }); })(i); }); 

你也可以把这个方法放到一个单独的函数中。 setupHandlers()立即执行,并绑定到正确的端口。

 for (var i = 0; i < ports.length; i++) { setupHandlers(ports[i]); } function setupHandlers(port) { port.on("open", function (path) { ports.write("Helo World\n", function(err,res) { if(err) console.log('err ' + err); console.log('results ' + res); }); ports.on("data", function (data) { console.log("here: "+data); }); }); }