2010-10-07 4 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! */; 
}; 

Я знаю, что там может быть способ сделать это, используя не-evented IO, но я предпочел бы ответ, что позволяет мне ждать evented функций так что я не застрял снова, если я приду в ситуацию, когда мне нужно сделать то же самое, но не с IO. Я знаю, что это нарушает идею «все это событие», и я не планирую использовать ее очень часто. Однако иногда мне нужна функция утилиты, которая отображает шаблон haml на лету или что-то в этом роде.

Наконец, я знаю, что могу называть fs.readFile и кэшировать результаты на ранней стадии, но это не сработает, потому что в этой ситуации «исходный файл» может меняться «на лету».

ответ

4

ОК, поэтому вы хотите, чтобы ваша версия разработки автоматически загружала и повторно отображала файл каждый раз, когда он менялся, не так ли?

Вы можете использовать fs.watchFile для контроля за файлом, а затем повторно визуализировать шаблон каждый раз, когда он изменился. Предположим, у вас есть какая-то глобальная переменная, в которой указано, работает ли сервер в dev или режиме производства:

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 собственности, когда это необходимо, в случае, если вы в моде разработки он будет автоматически повторно вынести этот файл каждый раз, когда она меняется.

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

Смежные вопросы