我有一个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请求一次,或者在初始化期间只执行一次,以及require()
结果是否在HTTP请求之间以某种方式缓存.
代码require
被提取并执行一次.在那之后,你会收到任何内容module.exports
,或者exports
.
每当第二次调用require
请求位于同一位置的内容时,它都会获得相同的引用module.exports
,或者exports
.
在您的特定情况下,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] foo
被立即抓取,因为是任何东西foo
require
S,module.exports
获取分配给a
.
[2]当调用此回调时,我们只是告诉express
,什么都不做,跳过我并转到下一个中间件.
[3]假设a
有一些字符串被分配到module.exports
内部foo
,它可以完全访问请求/foo
.
你需要考虑的是这些函数只是回调express
保持引用,并在它到达特定的一个时调用它们.它们按顺序处理,直到您调用next
,哪些瀑布进入下一个中间件.如果你不打电话next
,你应该结束回复.
我不确定你认为生命周期是如何工作的,但它可能不会像你想象的那样工作.节点只是坐着等待请求进入,然后一次处理一个,它永远不会停止,它永远不会真正"重新加载"任何东西.