2

nodejs 用の SerialPorts モジュールを使用しており、可変数のシリアル ポートを開き、書き込み、読み取ることができる必要があります。

だから私がやっていることは、最初に serialPort インスタンスの配列オブジェクトを作成し、次にそれらをループで処理することです:

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() 関数が実行されることですが、ポートを開いたり読み書きしたりしようとしません。

私は何を間違っていますか?? これを行うより良い方法はありますか??

4

1 に答える 1

2

ここにはいくつかの誤解があります。

まず、ポートを定期的にポーリングする必要はありません。Nodejs は (多かれ少なかれ) イベント ループを使用して IO を処理し、ポーリングを行います。したがって、openイベントのコールバックをポートごとに 1 回セットアップするだけで済みます。あなたのコードでは、呼び出されるたびにコールバックを読み込んでいるように見えますminute()。それは必要ありません。

次に、JavaScript には変数のブロック スコープがありません。代わりに、誤ってクロージャーを作成しており、コードにエラーがあります。この次のブロックでは:

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が呼び出されると、iinports[i].writeとの値は、期待どおり、コールバックが設定されたときのports[i].on("data")値ではありません。i代わりに、クロージャーを作成したため、コールバックが実行されるiまで、の値はバインド (設定) されません。この例では、すべてのコールバックが、最後に評価された値である に設定されます。iports.lengthi

for ループの問題を示す plunkr を作成しました。

この問題を解決する 1 つの方法は、匿名メソッドを使用して、値iを新しいローカル変数にバインドすることです。以下のコードでは、 がすぐに実行され、値が の適切な値に(function(index){})(i);バインドされます。indexi

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);
     });
  });
}
于 2013-07-02T00:05:41.017 に答える