1

わかりました、私が考え始めるのは難しいようです..ええと..機能的な方法..または非同期の方法。

私は node.js にはかなり慣れていませんが、c#、java、c++ で長年の経験があります。

Image 単純なタスクがあります。このタスクの考え方は、前の行が終了した直後に各行を実行する必要があるということです (ブロック操作)。C# での通常のアプローチとしましょう。また、(これがこの投稿の理由です) コードに 1 つの条件行があるとします。この擬似コードは次のようになります。

f = OpenFile("aaa.txt")
If f.ReadLine(1) == "bbb" // read the first line
    line = f.ReadLine(2)  // read the second line
else
    line = ReadLine(3)    // read the third line
DataBase.Insert(line)     // store the line in some database, lets say in mysql
DeleteFile(f)

ものすごく単純。現在、私が理解しているように、node.js はほぼすべての関数にコールバックを追加することにより、ノンブロッキング アプローチを使用しています。そうなると、この単純な作業が悪夢になりそうです。上記のコードを再現しようとすると、次のようになります。

OpenFile(f, function() {
    ReadLine(f, 1, function(line) {
        if line == "bbb" {
            ReadLine(f,2, function(line) {
                DataBase.Insert(line, function() {
                    DeleteFile(f);
                });
            });
        {
        else {
            ReadLine(f,3, function(line) {
                DataBase.Insert(line, function() { // the same again
                    DeleteFile(f);
                });
            });
        }
    });    

});

要点がわかります。この例では、ファイルが正常に開かれた後にのみ行の読み取りが行われるようにする必要がある場合、コールバックに「次の行のロジック」を記述する必要があります。そして、「前の行のコールバック」でのみ「次の行のロジック」を書き続ける必要があります。そうしないと、たとえば、開かれていないファイルの行を読み取ろうとするときに、状況に遭遇する可能性があります。また、実際のコードでは、次のようなノンブロッキング関数を実際に使用していることにも注意してください。

jsdom.env(..)
fs.exec(..)

上記のコードでの私のアプローチは正しいですか? または、何かを見逃していて、私のアプローチが完全に間違っていますか? より良い解決策とアプローチがあることを願っています。

お時間をいただきありがとうございます。

4

2 に答える 2

2

あなたのアプローチは正しいようです。それが機能する方法です。その通りです。非同期コードをスタイリッシュに記述する方法を見つけるのは困難です。

これを処理するツールの 1 つがStepで、これを使用すると、相互にコールバックとして機能する一連の関数を定義できます。

Step(
  function(...) {
    OpenFile...
  },
  function(...) {
    ReadLine(f, 2, this);
  },
  function(err, line) {
    if (err) throw err;
    if (line === "bbb")
      DataBase.Insert(line, this);
    else
      DataBase.Insert(line, this);
  },
  function(...) {
    DeleteFile...
  }
);

In Stepthisはコールバックとして機能し、指定されたシーケンスの次の関数に置き換えられます。並列タスクをトリガーすることも可能です。ドキュメンテーションは簡単です。

おそらくあなたはこの方法を好みます。


または追加のツールなし:

匿名関数をコールバックとして使用する必要はありません。関数を定義し、その名前をコールバックとして挿入できます。これにより、追加のツールなしでコードの重複を排除できます。小ドラフト:

OpenFile(f, function() {
    ReadLine(f, 1, function(line) {
        if line == "bbb" {
            ReadLine(f,2, insertIntoDatabaseAndDeleteFile);
        {
        else {
            ReadLine(f,3, insertIntoDatabaseAndDeleteFile);
        }
    });    

});

function insertIntoDatabaseAndDeleteFile(line, f) {
  DataBase.Insert(line, function() { 
      DeleteFile(f);
  });
}
于 2013-04-01T10:04:57.377 に答える
1

長年の C++ 開発者として、次のことをお伝えできます。

a) あなたのコードは大丈夫です b) あなたの気持ちも大丈夫です。c) 時間とともに良くなっている。それまでの間、私は C++ で同期 io 関数を呼び出すのが本当に不快に感じています。

これは、JS で何ができるかを示すコードの別のバージョンです。

OpenFile(f, function() {
    var myReadInsDel = function( f, n, callback ) {
        ReadLine(f,3, function( line ) {
            DataBase.Insert( line, function() {
                DeleteFile( f, callback );
            });
    });
    ReadLine(f, 1, function(line) {
        if line == "bbb" {
            myReadInsDel( f, 2 ); // you could provide also a callback here
        }
        else {
            myReadInsDel( f, 3 ); // you could provide also a callback here
        }
    });    
});
于 2013-04-02T07:10:25.147 に答える