Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/422.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node Js将文件交付给客户端_Javascript_Node.js - Fatal编程技术网

Javascript Node Js将文件交付给客户端

Javascript Node Js将文件交付给客户端,javascript,node.js,Javascript,Node.js,当您将HTML文件发送到客户端时,它会被解析并发出GET调用,以调用任何其他内容,如或(其中是否包含,我想是的) 执行此过程非常昂贵: 请求文件-客户端 从磁盘读取文件-节点 将内容发布到响应流-节点 读取响应流-客户端 当服务器启动时,是否仍要在节点中缓存文件内容,以便简单地执行此操作 请求文件-客户端 将内容发布到响应流-节点 读取响应流-客户端 我有这个功能,可以浏览scripts/文件夹中的所有脚本并读取文件: var gatherFiles = function () {

当您将
HTML
文件发送到客户端时,它会被解析并发出
GET
调用,以调用任何其他内容,如
(其中是否包含
,我想是的)

执行此过程非常昂贵:

  • 请求文件-客户端
  • 从磁盘读取文件-节点
  • 将内容发布到响应流-节点
  • 读取响应流-客户端
当服务器启动时,是否仍要在节点中缓存文件内容,以便简单地执行此操作

  • 请求文件-客户端
  • 将内容发布到响应流-节点
  • 读取响应流-客户端
我有这个功能,可以浏览
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
        });
    });
};
牢记这些要点

  • 它在一个树莓圆周率,它不需要是可伸缩的
  • 我不介意一开始是不是很贵
我假设,因为服务器应该只启动一次,所以如果所有文件在开始时都缓存在节点中,那么如果需要这些文件,就可以从内存中提供它们。这些文件都是脚本文件,所以它们不会太大,
100Kb
max(缩小后可能要小得多)

我问这个问题,因为当我做了
Chrome
Firefox
网络监视器来查看提供文件需要多长时间,而且需要很长时间,超过
100ms

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

因此,我认为我想用预缓存的方式来实现,它应该最小化
100ms
延迟

*我的解决方案*

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;
需要注意的要点是:

  • Async-each要求您启动一个回调,让它知道函数已完成,当它检测到所有回调已启动时,它将调用最终回调,这也允许允许错误通过
  • 在最后一次回调中,它调用主函数回调并通过文件字典传递数据,然后匿名函数应该启动http服务器
用法:

var cacher = require("./cacher");
cacher.gatherFiles(function (fileDictionary) {
    http.createServer(onRequest, 8888);
}, './Scripts');

我认为这样的东西会满足您的要求,即试图消除磁盘读取

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”)
相同,因为falsy条件会阻止进一步执行,因此警报永远不会到达。因此,如果您不传递回调,它将永远不会尝试执行回调。有点像故障保护。

只要确保添加了正确的标题,静态文件就会被浏览器缓存。@adeneo我想No1_Melman希望将文件缓存在服务器端(而不是浏览器),以避免多次读取文件。@san.chez-我明白了,我就是不明白why@adeneo这是因为每次从服务器调用它们都很昂贵。事实并非如此,Node可以毫无问题地处理数百万个静态资源请求,而且考虑到静态资源只在第一次由浏览器请求,因为它们应该在下次缓存,这是你拥有的最便宜的东西之一。另外,比较一下大多数用户的磁盘读取速度、内存速度和网络速度,想想什么时间最长。朋友,这是一个很好的答案,非常感谢您花费的时间和精力:)@No1_Melman请告诉我们结果。它将100ms的延迟减少了多少?@san.chez,我现在正在实施,将在bitCurrent Stats Ares(旧实施)中发回结果。但是,发送和接收文件所需的时间少于
40ms
,实际调用脚本文件需要
103ms
。@san.chez在预缓存文件时有一个
200ms
保存,我将在我的答案中发布一个编辑,说明我是如何做的