2014-01-26 31 views
0

第一個使用Node.js的應用程序,試圖在單個類中嘗試從文件中獲取內容,但順序並非如我所料。當然知識從我失蹤,你能告訴我爲什麼..Node.js中的單例同步問題readdir

Singleton類:

var Singleton = (function() 
{ 
    var _instance = null; 

    return new function() 
    { 
     this.Instance = function() 
     { 
      if (_instance == null) 
      { 
       _instance = new Foo(); 
      } 
      return _instance; 
     } 
    }; 
})(); 

Foo類:

var Foo= function Foo() 
{ 
    this._filesDir= "./core/files/"; 
    this._storedFiles = {}; 

    this.method1(); 
console.log("call constructor"); 
}; 

Foo.prototype = { 
    method1: function() 
    { 
     console.log("call method1"); 
     var that = this; 

     var c = 0; 

     fs.readdirSync(this._filesDir).forEach(function(fileName) 
     { 
      console.log("iterating file"+ c); 

      c++; 
      fs.readFile(that._filesDir + fileName, 'utf-8', function(err, content) 
      { 
       var clean_FileName = fileName.replace(".txt", ""); 
       console.log(clean_fileName); 
       that._storedFiles[ clean_fileName ] = content; 
      }); 
     }); 
    }, 

    method2: function(fileName) 
    { 
     console.log('call method2'); 
     return (fileName in this._storedFiles); 
    } 
}; 

調用:

console.log(Singleton.Instance().method2("myfile")); 

在目錄中,只有這個myfile.txt

但是,顯示我的控制檯:

call method1 
iterating file0 
call constructor 
call method2 
false 
GET /test 304 11ms 
myfile 

所以我的迴應是假的,是這個所謂的第三位置正常的構造函數?我需要類構造,存儲,並最終執行method2()。我做得不好?

回答

1

問題的根源在於fs.readFile是異步的。在讀取文件的內容之前,method1會返回。一個簡單的解決方法是將其更改爲fs.readFileSync

「調用構造函數」第三​​個原因是因爲您首先調用method1()。

this.method1(); 
console.log("call constructor"); 

在console.log(「調用構造函數」)發生之前,method1中的所有內容都會運行。如果您希望訂單是正確的,您可以簡單地交換兩者。

從高層次來說,使用同步調用(readdirSync,readFileSync)通常是一個壞主意,因爲它們阻止Node在運行時執行其他任何操作。我會建議研究回調,控制流和Node.js的異步性質。那裏有很多很棒的教程。

+0

就是這樣。關於概念問題,我整理了this.method1();從構造函數,並簡單地稱之爲應用程序的主要開始,而我最終編輯readdirSync readdir。謝謝 – Flozza