2010-10-07 87 views
1

我想製作一個node.js函數,它在調用時讀取文件並返回內容。我很難做到這一點,因爲'FS'已經完成了。因此,我的函數看起來像這樣:Node.js返回文件的結果

function render_this() { 
    fs.readFile('sourcefile', 'binary', function(e, content) { 
     if(e) throw e; 
     // I have the content here, but how do I tell people? 
    }); 
    return /* oh no I can't access the contents! */; 
}; 

我知道,有可能是一個辦法做到這一點使用非事件觸發IO,但我更喜歡一個答案,讓我對事件觸發功能等這麼如果我遇到需要做同樣事情的情況,而不是IO,我不會再被卡住。我知道這打破了「一切都是平衡」的想法,我不打算經常使用它。但是,有時候我需要一個實用的函數來動態地呈現haml模板或其他東西。

最後,我知道我可以在早期調用fs.readFile並緩存結果,但這樣做不起作用,因爲在這種情況下'sourcefile'可能會隨時更改。

回答

4

好的,所以你想讓你的開發版本自動加載並重新渲染文件,每次它的變化,對吧?

您可以使用fs.watchFile來監視文件,然後在每次更改模板時重新呈現模板,我想您的某個全局變量表示服務器是以開發模式還是生產模式運行:

var fs = require('fs'); 
var http = require('http'); 
var DEV_MODE = true; 

// Let's encapsulate all the nasty bits! 
function cachedRenderer(file, render, refresh) { 
    var cachedData = null; 
    function cache() { 

     fs.readFile(file, function(e, data) { 
      if (e) { 
       throw e; 
      } 
      cachedData = render(data); 
     }); 

     // Watch the file if, needed and re-render + cache it whenever it changes 
     // you may also move cachedRenderer into a different file and then use a global config option instead of the refresh parameter 
     if (refresh) { 
      fs.watchFile(file, {'persistent': true, 'interval': 100}, function() { 
       cache(); 
      }); 
      refresh = false; 
     } 
    } 

    // simple getter 
    this.getData = function() { 
     return cachedData; 
    } 

    // initial cache 
    cache(); 
} 


var ham = new cachedRenderer('foo.haml', 

    // supply your custom render function here 
    function(data) { 
     return 'RENDER' + data + 'RENDER'; 
    }, 
    DEV_MODE 
); 


// start server 
http.createServer(function(req, res) { 
    res.writeHead(200); 
    res.end(ham.getData()); 

}).listen(8000); 

創建cachedRenderer,然後訪問它需要的時候getData財產,如果你在開發MOD是它會自動在每次發生變化時重新渲染文件。

0
function render_this(cb) { 
    fs.readFile('sourcefile', 'binary', function(e, content) { 
     if(e) throw e; 
     cb(content); 
    }); 
}; 


render_this(function(content) { 
    // tell people here 
}); 
+0

我寧願不用回調來做這件事。在這種情況下,我試圖編寫一個呈現haml模板的函數。在生產服務器上,它應該在服務器statup上緩存模板並在調用時渲染它,但在開發服務器上它應該讀取每次調用的文件以防萬一它改變了。因此,我想要一個讀取文件的開發函數,但假設它沒有。回調改變了我的功能的類型簽名,這使得切換到生產模式變得非常困難。 – So8res 2010-10-07 01:41:28