跳过补间模块时,'TypeError:undefined不是函数'

[英]'TypeError: undefined is not a function' when jumping 'tween modules


I keep getting this issue in Node where my application crashes whenever I'm calling functions from one another.

我一直在Node中遇到这个问题,每当我调用彼此的函数时,我的应用程序就会崩溃。

I've made this minimum working example (working as in it gives me the error):

我已经做了这个最小的工作示例(工作因为它给了我错误):

Start module

启动模块

var module2 = require('./module2');

var data = 'data';

module2.doStuff(data);

Module2

单词数

var module3 = require('./module3');

function doStuff(data){
    // Stuff happens to 'data'
    module3.takeStuff(data);
}

function doSomethingElse(data){
    console.log(data);
}


module.exports = {
    doStuff: doStuff,
    doSomethingElse: doSomethingElse
};

Module3

单词数

var module2 = require('./module2');

function takeStuff(data){
    // Stuff happens to 'data'
    module2.doSomethingElse(data); // I get the type error here
}

module.exports = {
    takeStuff: takeStuff
};

The error I get is:

我得到的错误是:

module2.doSomethingElse(data); // I get the type error here
        ^
TypeError: undefined is not a function

The start module calls a function in module2 which ultimately calls for a function in module3, which in turn calls for a function in module2.

start模块调用module2中的一个函数,该函数最终调用module3中的一个函数,该函数又调用module2中的函数。

All modules are properly required and it finds the first method in module2 just fine.

所有模块都是正确需要的,它在module2中找到第一个方法就好了。

What's happening here and how would one go about this pattern when one needs to get a function from the module one came with?

这里发生了什么,当一个人需要从模块中获取一个函数时,如何处理这种模式?

EDIT

编辑

Debugging shows me that the module exists, but it's empty apart from the prototype it has. My question is why? Inside of Node/JavaScript, what's happening here?

调试显示模块存在,但它与原型相比是空的。我的问题是为什么?在Node / JavaScript里面,这里发生了什么?

2 个解决方案

#1


4  

You've got a circular reference, module 2 depends on module 3 which depends on module 2 which depends on module 3 (and so on). So while trying to resolve module 3 for module 2, it cannot complete it because module 3 itself needs to be resolved first.

你有一个循环引用,模块2依赖于模块3,模块3依赖于模块2,模块2依赖于模块3(依此类推)。因此,在尝试解析模块2的模块3时,它无法完成它,因为模块3本身需要首先解析。

From https://nodejs.org/api/modules.html#modules_cycles:

来自https://nodejs.org/api/modules.html#modules_cycles:

When there are circular require() calls, a module might not have finished executing when it is returned.

当有循环的require()调用时,模块在返回时可能没有完成执行。

In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the b.js module.

为了防止无限循环,a.js导出对象的未完成副本将返回到b.js模块。

So the module is available, but incomplete (which explains that you only receive a prototype). Circular references are a code smell anyway, try to avoid it :)

所以该模块可用,但不完整(这说明您只收到原型)。循环引用无论如何都是代码味道,试着避免它:)

However, if you put both module 2 and 3 as a dependency in your starting module, it should work anyway.

但是,如果您将模块2和3都作为依赖项放在启动模块中,那么无论如何它都应该工作。

var module2 = require('./module2');
var module3 = require('./module3');

var data = 'data';

module2.doStuff(data);

#2


6  

This issue here can be easily fixed, while keeping the structure of your app (which is fine, in regard to circular references).

这个问题可以很容易地修复,同时保持你的应用程序的结构(这对于循环引用来说很好)。

You just need need to keep the default exports object that is given to your modules by the system. Do not change it with module.exports = {...}.

您只需要保留系统为模块提供的默认导出对象。不要使用module.exports = {...}更改它。

The following should work:

以下应该有效:

Start module

var module2 = require('./module2');

var data = 'data';

module2.doStuff(data);

Module 2

var module3 = require('./module3');

exports.doStuff = function doStuff(data){
    // Stuff happens to 'data'
    module3.takeStuff(data);
};

exports.doSomethingElse = function doSomethingElse(data){
    console.log(data);
};

Module 3

var module2 = require('./module2');

exports.takeStuff = function takeStuff(data){
    // Stuff happens to 'data'
    module2.doSomethingElse(data); // I get the type error here
};

Explanation

I'll try to explain what happens from the first line of your starting point:

我将尝试解释从起点的第一行发生的事情:

  1. In start.js, you require module2 and it is not loaded yet: the code from module2.js is executed
  2. 在start.js中,您需要module2并且尚未加载:执行module2.js中的代码
  3. In module2.js, you require module3 and it is not loaded yet: the code from module3.js is executed
  4. 在module2.js中,您需要module3并且尚未加载:执行module3.js中的代码
  5. In module3.js, you require module2, and it is already loaded: the module2 variable now contains the exports object from module2.
  6. 在module3.js中,您需要module2,并且它已经加载:module2变量现在包含来自module2的exports对象。
  7. The rest of module3 is executed and you change its exports object with module.exports = {...}
  8. 执行module3的其余部分,并使用module.exports = {...}更改其导出对象
  9. In module2.js, the module3 variable now contains the exports object from module3.
  10. 在module2.js中,module3变量现在包含来自module3的exports对象。
  11. The rest of module2.js is executed and you change its exports object with module.exports = {...}
  12. 执行module2.js的其余部分,并使用module.exports = {...}更改其exports对象
  13. In start.js, the module2 variable now contains the exports object from module2.
  14. 在start.js中,module2变量现在包含来自module2的exports对象。

The issue here is between points 3 and 6. Module3 is receiving the exports of module2 (3) before you change the reference to it (6). Using exports.method = ... solves the problem because the exports object never changes.

这里的问题是在第3点和第6点之间。在更改对它的引用之前,Module3正在接收module2(3)的导出(6)。使用exports.method = ...解决了问题,因为exports对象永远不会更改。

智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2015/08/03/7def5a0f1dbb8ceaa5c83dc04118a708.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告