节点Js将文件传递给客户端

时间:2013-12-28 19:42:12

标签: javascript node.js

当您向客户端发送HTML文件时,会对其进行解析并对其他任何内容进行GET调用,例如<SCRIPT><LINK><IMG>包括在内?我认为是。)

执行此过程非常昂贵:

  • 询问文件 - CLIENT
  • 从磁盘读取文件 - NODE
  • 将内容发布到Response Stream - NODE
  • 读取响应流 - CLIENT

当服务器启动时,无论如何都要在Node中缓存文件内容以便完成

  • 询问文件 - CLIENT
  • 将内容发布到Response Stream - NODE
  • 阅读响应流 - 客户端

我有这个功能来浏览Scripts/文件夹中的所有脚本并阅读文件:

var gatherFiles = function () {
    fs.readdir('/Scripts', function (err, files) {
        files.filter(function (file) {
            return path.extname(file) == '.js';
        }).forEach(function (file) {
            // read files here
        });
    });
};

记住这些要点

  • 它在Raspberry Pi上,它不需要是可扩展的
  • 我不介意一开始是否很贵

我认为,因为服务器应该只启动一次,如果所有文件在开始时都缓存在节点中,那么如果需要它们,那么它们可以从内存中提供。这些文件是脚本文件,因此它们不是很大,100Kb最大值(在缩小之后可能更少)。

我问这个,因为当我完成ChromeFirefox网络监视器以查看提供文件所需的时间,并且需要很长时间,超过{{ 1}} ...

我猜测服务器的许多部分都存在延迟:以太网,SD卡,代码。

所以我认为我希望通过预缓存来实现它,它应该最小化100ms滞后。

*我的解决方案*

100ms

需要注意的要点是:

  • 异步每个都要求你有一个回调被激活,让它知道一个函数已经完成,当它检测到所有回调被触发然后它将调用最终的回调,这也允许错误通过。
  • 在最后的回调中,它调用main函数回调并通过带有数据的文件字典,然后匿名函数应该启动http服务器

用法:

var fs = require ("fs"),
    path = require("path"),
    async = require("async"),
    scriptFiles = {};

function gatherFiles(callback, folder) {
    fs.readdir(folder, function (err, files) {
        var filteredFiles = files.filter(function (file) {
            var ext = path.extname(file);
            return ext == '.js' || ext == '.html';
        });
        aync.each(filteredFiles, function (file, asynCallback) {
            if (!scriptFiles[file])
                fs.readFile(folder + '/' + file, function (err, data) {
                    scriptFiles[file] = data;
                    asyncCallback();
                });
        }, function (err) {
            callback(scriptFiles);
        });
    });
};

exports.gatherFiles = gatherFiles;

1 个答案:

答案 0 :(得分:3)

我认为这样的事情会满足你的目标,这就是试图消除磁盘读取。

function Files = function () {
    var files = {};

    return function (filepath, callback) {
        // If cache is available, return that
        if (files[filepath]) return callback(null, files[filepath]);
        // Otherwise, get it, then store it
        fs.readFile(filepath, function (err, data) {
            if (err) return callback(err);
            files[filepath] = data;
            callback(null, data);
        });
    }
}();

然后将其称为

Files('/scripts/whatever.js', function (err, data) {
   // Do something
});

如果您愿意,可以添加其他功能,例如文件监视或缓存过期。

如果你想在开始时将它们全部缓存,你可以遍历任何目录并且不对回调做任何事情。

为此我会修改它:

//...
if (files[filepath]) return callback && callback(null, files[filepath]); 
//...
callback && callback(null, data);
//...

callback && callback(...)将被视为与if (false && alert("Nothing"))相同,因为永远不会达到警报,因为虚假条件会阻止进一步执行。因此,如果您没有传递回调,它将永远不会尝试执行回调。排除故障安全。