为什么在NodeJS中使用“ require”时会有如此奇怪的行为?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么在NodeJS中使用“ require”时会有如此奇怪的行为?相关的知识,希望对你有一定的参考价值。

[当我在ClassB中导入ClassA,然后在ClassB中导入ClassA时,导入的ClassA是一个空对象。为了演示,我有以下3个文件:

ClassA.js

const ClassB = require('./ClassB');

class ClassA {
    static test() {
        ClassB.test();
    }
}

module.exports = ClassA;

ClassB.js

const ClassA = require('./ClassA');

class ClassB {
    static test() {
        console.log('ClassA.test', ClassA.test);
    }
}

module.exports = ClassB;

index.js

const ClassA = require('./ClassA');

ClassA.test();

[当我运行node index.js时,我希望在控制台中看到ClassA.test function,但它将输出ClassA.test undefined。是一些未记录的东西,还是一个错误?

答案

您具有循环依赖关系。解决方案是让第三个类同时需要这两个类,并使用您从ClassA中的ClassB中获得的任何代码,反之亦然。

const ClassA = require('./ClassA');
const ClassB = require('./ClassB');

class ClassC {
    static test() {
        ClassA.test();
        ClassB.test();
    }
}

运行节点index.js时,我希望看到ClassA.test函数控制台,但是它输出ClassA.test未定义。有吗没有记载的东西,还是一个错误?

不,这不是错误,并且没有记载。

您可以在此处阅读有关其处理方式的更多信息:https://nodejs.org/api/modules.html#modules_cycles


您也可以进行延迟加载,并将针对此特定情况解决您的问题。但是在大多数情况下,循环引用是编写不良代码的征兆。

class ClassB {
    static test() {
        const ClassA = require('./ClassA')
        console.log('ClassA.test', ClassA.test);
    }
}

module.exports = ClassB;
另一答案

您具有循环依赖关系,因此Node无法确定哪个模块的顶级代码应首先运行-one这些模块需要首先运行其顶级代码,以便导出某些内容这样其他模块就可以通过require导入它。但是,如果两者都依赖于另一个,则第一个运行的将对另一个解析为require的对象调用undefined

最好的解决方案是重构它以避免循环依赖。

以上是关于为什么在NodeJS中使用“ require”时会有如此奇怪的行为?的主要内容,如果未能解决你的问题,请参考以下文章

NodeJs模块加载流程分析(require)

为啥 nodejs 可能找不到“require”?

在nodejs中避免../../../ require [重复]

命名空间“NodeJS”没有导出成员“Require”

Mongolab nodejs拓扑被破坏

Mongolab nodejs拓扑被破坏