Node.js的困惑于非阻塞方法

时间:2013-04-01 09:45:51

标签: node.js callback nonblocking

好吧,似乎我很难开始思考..嗯..功能方式..或异步方式。

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

我在上面的代码中的方法是否正确?或者我错过了什么,我的做法完全错了?我希望有更好的解决方案和方法。

感谢您的时间。

2 个答案:

答案 0 :(得分: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);
  });
}

答案 1 :(得分:1)

作为一名长期的C ++开发人员,我可以告诉你:

a)你的代码是o.k. b)你的感受是o.k.太。 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
        }
    });    
});
相关问题