跳過補間模塊時,'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對象永遠不會更改。


注意!

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



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