Nodejs require合理用法请教

Nodejs require合理用法请教

请教一个node.js的require用法
a.js/b.js/c.js三个在同一目录下
a.js包含b.js和c.js,但b.js和c.js也需相互调用,所以也想相互包含(但发现b.js和c.js里面的想互包含有一个会失败,失败哪个取决于他们在a.js中被包含时的先后顺序)
运行
node a.js

ps:我现在是通过在a.js全局变量(即不用var声明变量),然后b.js和c.js不包含任何其它文件,直接用全局变量调用,来解决的

1.我想问,在node.js中,一般这种解决方案什么样的啊? 还是说就是我上面的这种用法?? 2.还是说我这个结构本身有问题??但感觉相互调用在业务逻辑中还是会存的吧


10 回复

针对你提到的 Node.jsrequire 的合理使用方法,我们可以探讨一下更清晰、模块化的设计方案。你当前的方法虽然可以工作,但可能会导致一些潜在的依赖问题和代码难以维护。

示例代码

首先,我们先看一下你描述的目录结构:

/project-root/
  /src/
    a.js
    b.js
    c.js

a.js

const b = require('./b');
const c = require('./c');

// 使用 b 和 c
console.log(b.someFunction());
console.log(c.someOtherFunction());

b.js

const c = require('./c'); // 在这里引入c.js

module.exports = {
  someFunction: function() {
    return 'This is from B, and I can call C: ' + c.someOtherFunction();
  }
};

c.js

const b = require('./b'); // 在这里引入b.js

module.exports = {
  someOtherFunction: function() {
    return 'This is from C, and I can call B: ' + b.someFunction();
  }
};

解释

  1. 避免循环引用:在你的例子中,b.jsc.js 相互引用。理论上,这会导致一个循环引用的问题。然而,Node.js 能够处理这种情况,因为它们都是同步加载的,只要确保在模块内部定义好函数或对象。

  2. 模块导出:每个文件都通过 module.exports 导出它们需要共享的功能。这样可以避免全局变量的滥用,使代码更加模块化和易于测试。

  3. 合理组织代码:将功能相关的代码放在单独的模块中,并通过 require 引入它们。这样可以避免在全局作用域中创建不必要的变量,减少命名冲突的风险。

结论

你目前的解决方案不是最理想的,因为它依赖于全局变量。使用 require 模块化地导入和导出功能是一个更好的做法。这样不仅代码更清晰,也更容易维护和扩展。如果你确实需要模块之间相互调用,确保它们的依赖关系是明确且合理的,避免循环引用带来的复杂性。


要么抽个 d 出来让 b 跟 c 去依赖 d 去. 要么就是 b 跟 c 合体.

楼上是想说,相互引用确认是不行的???

刚在Stack Overflow看到一个方法,即在b.js中可以耦合c.js,但在c.js中如何获得b.js引用,则通过在a.js中包含c.js时,调用c.js的一个init函数,将b.js的引用做为参数传递进去。。。好像也是一个方法就是了

并不确定没办法. 但不觉得这样搞代码很恶心么…

面向对象,对象啊… 哪能像PHP这么包含,思维都是错误的

全局变量这么用很危险。出错都找容易不到在哪里变动了。好好封装一下吧。

场景好像没描述清楚

你这个问题我遇到过类似的,我当时要做的大概是这样的。我写了一个JSONValidation.js,他是一个类文件,有一个vali的方法,其中要传入验证的对象obj,验证的规则schema等。问题就在这里了。schema本身也是一个json,我是用一个json-schema去验证一个json-obj,流程是可以实施,能有效控制json-obj,但是却没有代码能控制json-schema,如果json-schema不进行控制,就相当于配置了错误的验证规则。于是就有2种解决思路,第一种是让所有的程序员必须按照json-schema的规则去写,否则错误自己承担,第二种就是我能去验证json-schema,并在错误的时候提醒程序员。我当时采用了后者,我是用JSONValidation去解析我的参数json-schema,此时就出现了问题。这个工具类只能解析外部的json数据,却无法解析内部的json数据,因为解析外部的时候,其实他内部的所有构造都已经实例化了,不会有组件缺失。二让他解析内部参数的时候,因为他还没有完全实例化,只是接收到了参数,因此就会出现错误。 你的问题就是你在使用这些类文件的时候,是否将文件里的构造封装成类,是已经实例化好的还是需要通过某些手段间接实例化的。你采用全局对象的方式,其实就是默认将其一开始全部实例化好,所以不会出现组件缺失的问题。因此你需要通过画时序图和类图来确认:

  1. 你有哪些类、组件
  2. 这些类和组件的引用关系
  3. 他们的生命周期 当然你不这么研究也是可以的,那就是要全部采用全局的方式,java中就是static方式,东西写大了带来的问题你也清楚是吧,总而言之,确保你的a.jsb.jsc.js在相互引用的时候,所需要的组件或者参数都是已经实例化好的

在Node.js中,require机制允许模块之间互相引用,但是需要谨慎处理以避免循环依赖问题。你提到的情况属于典型的循环依赖问题,可以通过一些设计模式来优化。以下是一些建议:

示例代码

假设你的目录结构如下:

/project-root/
├── a.js
├── b.js
└── c.js

b.js 和 c.js 的实现

首先,b.jsc.js 不应该直接互相引用。而是应该让 a.js 来管理它们之间的交互。这样可以避免循环依赖问题。

b.js

// b.js
module.exports = {
    doSomething() {
        console.log("Doing something in b.js");
    }
};

c.js

// c.js
module.exports = {
    doSomething() {
        console.log("Doing something in c.js");
    }
};

a.js

// a.js
const b = require('./b');
const c = require('./c');

// 使用 b 和 c 进行交互
b.doSomething();
c.doSomething();

// 如果需要 b 和 c 相互调用,可以在 a.js 中进行适配
b.interactWithC(c);
c.interactWithB(b);

解释

  1. 避免循环依赖:将模块的相互调用逻辑放在 a.js 中,而不是在 b.jsc.js 中。
  2. 接口设计:为 b.jsc.js 提供清晰的接口,以便在 a.js 中进行调用。
  3. 全局变量:避免使用全局变量,这会导致代码难以维护。

结论

  1. 合理的解决方案:通过在 a.js 中管理 b.jsc.js 之间的交互,可以有效避免循环依赖问题。
  2. 结构合理性:你的结构本身没有问题,只是需要调整设计方式来处理循环依赖问题。通过这种方式,可以确保代码更清晰、更易于维护。

希望这个答案能帮助你理解如何合理地使用 require 以及如何处理循环依赖问题。

回到顶部