2013-04-01 62 views
1

好吧,似乎我很難開始思考..恩..功能方式..或異步方式。Node.js.與非阻塞方法相混淆

我是相當新的node.js的,但我有多年的C#,JAVA,C++經驗..

圖片我有簡單的任務。這個任務的想法是每行應該在上一行完成後執行(阻塞操作)。正常的做法,讓我說,C#。此外,(這是這篇文章的原因)讓我們想象我們的代碼中有一條條件線。這個僞代碼將如下:

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(..) 

是我在上面的正確的代碼的做法還是我想念的東西,我的做法?是完全錯誤的?我希望有一個更好的解決辦法和途徑。

謝謝您的時間。

+0

你是正確的,它可能很難改變你的想法。代碼不容易閱讀。但是Node不能將異步任務中的線性代碼分離出來(這真是太棒了!) – TheBronx

回答

2

你的做法似乎是正確的,這就是它的工作方式。而你是正確的,很難找到一種時尚的方式來編寫異步代碼。

一個工具處理這是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... 
    } 
); 

在步驟this充當回調和由從下面的函數替換給定的順序。也可以觸發並行任務。文檔很簡單。

也許你更喜歡這種方式。


或沒有額外的工具:

沒有必要使用匿名函數作爲回調。您可以定義一個函數並將其名稱作爲回調函數來使用,從而可以在不使用其他工具的情況下消除代碼重複。小稿:

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); 
    }); 
} 
+0

好吧,它似乎對我的大腦來說是曲折的......但沒關係。 – Astro

1

作爲一個長期的C++開發者,我可以告訴你:

一)你的代碼是O.K. b)你的感覺是o.k.太。 c)時間越來越好。在此期間,我感覺真的很不舒服調用同步IO-功能在C++

這裏是你的代碼的另一個版本,給你一個印象,你可以在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 
     } 
    });  
});