在使用 Express.js 开发 Web 应用程序时,有时会碰到 “循环引用” 的问题。这种问题常常导致程序出现错误或者一直处于卡顿状态。解决起来也并不是很容易,那么我们该如何解决这种问题呢?
什么是 “循环引用” ?
首先,我们需要了解一下什么是 “循环引用”。 “循环引用” 通常是指两个或多个模块(文件)互相引用,形成一个环状的依赖关系。
举个例子,假设有两个模块 A 和 B:
-- -------------------- ---- ------- -- ---- ----- - - --------------- --- -- ---- ----- - - --------------- ---
上面的代码就形成了一个循环引用,因为 A.js 引用了 B.js,而 B.js 又引用了 A.js。
“循环引用” 问题的原因
在 Express.js 中,我们可能会将一些逻辑或者处理请求的过程拆分成不同模块,然后在其中引用其他模块中的函数或者对象,这时候就可能会遇到 “循环引用” 问题。如果两个模块都引用了对方,就会导致循环引用的问题。
例如,我们有一个 login.js 模块和一个 user.js 模块,假设 login.js 要使用 user.js 中的 checkUser 函数进行用户验证,而 user.js 中要使用 login.js 中的 getUserInfo 函数获取用户信息,代码如下所示:
-- -------------------- ---- ------- -- -------- ----- ---- - ------------------ -------- ------- - -- ------ ----- -------- - ------------------- -- ---- ----- ------ - ------------------------- --- - --- -- ------- ----- ----- - ------------------- -------- ------------- - --- ------ --- - -------- ------------------- - -- ------ --- -- ----- ----- ---- - ---------------- --- - --- -------------- - - ------------ ---------- --
上述代码就会导致循环引用的问题,由于 login.js 和 user.js 互相引用,无法决定哪个先执行,从而导致了程序出错。
解决 “循环引用” 问题
方法一:重构代码结构
这种方法需要我们思考一下整个程序的架构,看看有没有什么方式能够使得两个模块不再互相依赖。在上述例子中,我们可以将获取验证码的代码移动到单独的一个 captcha.js 模块中,然后 login.js 和 user.js 分别引用即可:
-- -------------------- ---- ------- -- -------- ----- ------- - --------------------- ----- ---- - ------------------ -------- ------- - -- ----- ----- ---- - ------------------ --- -- ------ ----- -------- - ------------------- -- ---- ----- ------ - ------------------------- --- - --- -- ------- -------- ------------- - --- ------ --- - -------- ------------------- - -- ------ --- -- ----- ----- ------- - --------------------- ----- ---- - ------------------ --- - --- -- ---------- -------- --------- - --- - --- -------------- - - -------- --
这样一来,我们就解决了 “循环引用” 的问题。
方法二:延迟引用
上述重构代码结构的方法,往往需要我们改变程序的原有结构,修改原有代码,这是一种比较耗时的方式。另外一种比较简单的方式是采用延迟引用的方法。
如果我们在某个模块中使用到了另外一个模块,但这个模块也会使用到当前模块时,我们可以使用 require 方法来引入另一个模块的文件,并将其赋值给一个变量。但是,在当前模块中使用变量之前,我们需要将其先设置为 null,然后在需要使用时,再重新赋值。这样就可以延迟引用,解决 “循环引用” 的问题。
-- -------------------- ---- ------- -- -------- --- ---- - ----- -------- ------- - -- ------ ---- - ---- -- ------------------ ----- -------- - ------------------- -- ---- ----- ------ - ------------------------- --- - --- -- ------- --- ----- - ----- -------- ------------- - --- ------ --- - -------- ------------------- - -- ------ --- -- ----- ----- - ----- -- ------------------- ----- ---- - ---------------- --- - --- -------------- - - ------------ ---------- --
上述代码中,我们使用了 let user = null 和 let login = null 来定义变量,并将其赋值为 null。然后,我们在需要使用对应模块时,通过 user = user || require('./user') 或者 login = login || require('./login') 来进行延迟引用。
总结
“循环引用” 是一种比较麻烦的问题,但并不是不能解决。我们可以通过重构代码结构或者使用延迟引用的方式来解决这个问题。在实际开发中,我们可以结合具体的场景,采用不同的解决方式,来避免循环引用带来的问题。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6517c43f95b1f8cacdfec57c