在Express.js应用程序中要求()的东西有多贵?

时间:2014-01-01 23:56:44

标签: javascript node.js express

我有一个Express.js网络应用程序正在为我的某个域提供服务。 app.js文件如下所示:

var express = require('express');
var app = express();

// and so on…

我想在app.js文件中使用我自己的一个函数,所以我想我将函数放在一个单独的文件中(作为一个模块,即module.exports =个东西)然后在app.js文件中要求它:

var myfunc = require('./path/to/myfunc');

然而,我担心表现。在Express.js应用程序中需要文件时是否会有明显的性能损失?我想这个问题归结为执行app.js代码的次数 - 每次我的域的HTTP请求一次或初始化期间只执行一次,以及是否在HTTP请求之间以某种方式缓存require()结果

2 个答案:

答案 0 :(得分:7)

代码require被提取并执行一次。之后,您将返回module.exportsexports中的所有内容。

每当第二次呼叫require请求位于同一位置的内容时,它都会获得与module.exportsexports相同的引用。

在您的特定情况下,代码require d在引导应用程序时require d一次,同时引导。

然后,每当请求require还没有require时,它就被获取并执行。在此之后的每一次,require次调用都只会获取缓存的数据。

还记得节点是如何单线程的吗?这就是为什么如果你尝试require一个不存在的文件,你就会把整个过程都搞砸了。

更新

回答Šime的问题,关于“何时”require来电被执行。

require调用在执行代码时会被执行,没有预处理或任何花哨的魔法。如果请求的一部分可以访问该范围,则整个过程将有效地“共享”所有不属于请求的内容。

让我们看一个例子。假设这是你的app.js,为了简洁,我忽略了所有不相关的快速引导代码。

var a = require('./foo.js'); // [1]

app.get('/thing', function (req, res, next) {
    next(); // [2]
});

app.get('/thing', function (req, res, next) {
    res.end();
});

app.get('/foo', function (req, res, next) {
    res.end(a); // [3]
});
立即获取

[1] foofoo requiremodule.exportsa分配给express

[2]当调用此回调时,我们只是告诉a,什么也不做,跳过我并转到下一个中​​间件。

[3]假设module.exportsfoo内为/foo分配了一些字符串,则对express的请求完全可以访问。

您需要考虑的是这些函数只是回调next保持引用,并在它到达特定的一个时调用它们。它们按顺序处理,直到您调用next,它会进入下一个中间件。如果您不致电{{1}},则应该结束回复。

我不确定你认为生命周期是如何运作的,但它可能不会像你想象的那样发挥作用。节点只是坐在那里等待请求进来,然后一次处理一个,它永远不会停止,它从来没有真正“重新加载”任何东西。

答案 1 :(得分:3)

来自docs

  

模块在第一次加载后进行缓存。这意味着(除其他外)每次调用require('foo')将获得完全相同的返回对象,如果它将解析为同一个文件。

第一次加载后,require调用中唯一的额外开销是解析文件的路径。通常,对require的所有调用都放在文件的顶部。