[英]Uncaught TypeError: <function> is not a function
I am pretty new to Javascript and I've across an issue I can't seem to understand. 我对Java语言还很陌生,遇到了一个我似乎无法理解的问题。 The console is complaining saying it is not recognising the function. 控制台抱怨说无法识别该功能。
I have the following code (GraphActions.js): 我有以下代码(GraphActions.js):
var VentureDispatcher = require('../dispatcher/VentureDispatcher');
var GraphStoreConstants = require('../constants/GraphStoreConstants');
var StockService = require('../utils/StockService');
var GraphActions = {};
GraphActions.getGraphData = function(request){
//have the API call here.
VentureDispatcher.handleViewAction({
actionType: GraphStoreConstants.GET_GRAPH_DATA,
data: request
});
StockService.getHistoricStockData(request);
};
GraphActions.recieveGraphData = function(response){
VentureDispatcher.handleServerAction({
actionType: GraphStoreConstants.GRAPH_DATA_RESPONSE,
response: response
});
};
GraphActions.test = function(){
console.debug("found this.");
};
module.exports = GraphActions;
And the following Javascript file which is calling the function within the code above: 以下是在上述代码中调用该函数的Javascript文件:
var request = require('superagent');
var GraphActions = require('../actions/GraphActions');
var StockService = {
getHistoricStockData: function(symbol){
request.post('http://localhost:8080/historicalData')
.send({
"symbol":"GOOG",
"from":"2016-06-01",
"to":"2016-07-01"
})
.set('Content-Type','application/json')
.end(function(err,res){
if(err || !res.ok){
console.error('Error making request!');
}else {
console.debug(JSON.stringify(res.body));
GraphActions.recieveGraphData(res.body);
}
});
}
};
module.exports = StockService;
The console is throwing the following error and not too sure why: venture-stock.js:44673 Uncaught TypeError: GraphActions.recieveGraphData is not a function. 控制台将引发以下错误,但并不太确定原因:Venture-stock.js:44673未捕获的TypeError:GraphActions.recieveGraphData不是一个函数。
Does anyone understand why this is happening? 有谁知道为什么会这样? The same method has been called in another place with no problem. 相同的方法已在另一个位置成功调用。
When debugging the code and evaluating GraphAction object in the above code I get the following where the functions defined above are not available: 当调试代码并评估以上代码中的GraphAction对象时,我得到以下内容,其中上面定义的功能不可用:
Where as in another location, the functions are available: 在其他位置,这些功能可用:
Any help would be appreciated! 任何帮助,将不胜感激!
It happens because of a circular reference among your modules. 发生这种情况是因为模块之间存在循环引用。 The module GraphActions
requires the module StockService
, which also requires GraphActions
. GraphActions
模块需要StockService
模块,后者还需要GraphActions
。 It doesn't matter if what's actually needed in StockService
it's the recieveGraphData
method, while the method that requires StockService
is getGraphData
: the module loader doesn't have this level of code analysis. 不管实际需要在StockService
什么是recieveGraphData
方法,而需要StockService
的方法是getGraphData
:模块加载器没有这种级别的代码分析。 require
would always return the whole module, so it's a circular reference. require
将始终返回整个模块,因此它是一个循环引用。
So, what happens in these cases? 那么,在这些情况下会发生什么?
The module loader, when loading GraphActions
, meets require('../utils/StockService')
, then stops the execution of GraphActions
in order to load StockService
. 模块加载器在加载GraphActions
时满足require('../utils/StockService')
,然后停止执行GraphActions
以便加载StockService
。 At this point, the exported properties of GraphActions
are... none. 此时, GraphActions
的导出属性为...无。 So that's why in StockService
you get an empty object. 这就是为什么在StockService
会得到一个空对象的原因。
Merge the two modules in one, eg 将两个模块合并为一个,例如
var GraphService = {
getGraphData: function(request) {
...
GraphService.getHistoricStockData(request);
},
recieveGraphData: function(response) { ... },
getHistoricStockData: function(symbol) {
...
GraphService.recieveGraphData(res.body);
}
};
module.exports = GraphService;
It's the opposite, ie decouple getGraphData
and recieveGraphData
in two different modules. 相反,即在两个不同的模块中解耦getGraphData
和recieveGraphData
。 I don't really like this one, because it can lead to excessive module fragmentation. 我真的不喜欢这个,因为它可能导致过多的模块碎片。
As long as CommonJS is used, you can take advantage of using require
wherever you want, so in StockService.js
you'd do: 只要使用CommonJS,您就可以在任何require
地方利用require
,因此在StockService.js
您可以这样做:
getHistoricStockData: function(symbol) {
request.post('http://localhost:8080/historicalData')
...
.end(function(err, res) {
...
var GraphActions = require('../actions/GraphActions');
GraphActions.recieveGraphData(res.body);
});
}
Now, since the execution will not immediately require GraphActions
, the module will be loaded later when all its dependencies are fully loaded, so you'll get a fully working module. 现在,由于执行将不会立即需要GraphActions
,因此将在模块的所有依赖项完全加载后再加载该模块,因此您将获得一个完全正常工作的模块。
In ES6, you cannot use import
outside the root level, ie you can't use import
inside a function. 在ES6中,不能在根级别之外使用import
,即,不能在函数内部使用import
。 So you couldn't use solution C with ES6 syntax? 因此,您不能将解决方案C与ES6语法一起使用?
Actually that wouldn't be necessary to begin with, because CommonJS module resolution is different than ES6's, the latter being more advanced. 实际上,一开始就没有必要,因为CommonJS模块的解析度不同于ES6的解析度,后者更为先进。 So, you'd have written: 因此,您将编写:
import * as StockService from '../utils/StockService';
...
export function getGraphData(request) {
...
StockService.getHistoricStockData(request);
};
export function recieveGraphData(response) { ... };
export function test() { ... };
and in StockService.js
: 并在StockService.js
:
import * as GraphActions from '../actions/GraphActions';
...
export function getHistoricStockData(symbol) {
request.post('http://localhost:8080/historicalData')
.send( ... )
.set('Content-Type','application/json')
.end(function(err, res) {
...
GraphActions.recieveGraphData(res.body);
});
};
So what happens here? 那么这里发生了什么? GraphActions.js
is loaded, the import
statement is reached, the execution of the module stops and then StockService
is loaded. 加载GraphActions.js
,到达import
语句, 停止执行模块 ,然后加载StockService
。 So far, it's the same as CommonJS. 到目前为止,它与CommonJS相同。
In StockService
, the loader would meet the import
statement, then the execution of GraphActions
resumes and the whole module is correctly exported. 在StockService
,加载程序将满足import
语句,然后恢复执行GraphActions
并正确导出整个模块。 So you'd be golden from the start with ES6. 因此,从一开始,ES6就让您大开眼界。
This will lead us to 这将导致我们
Since you're already using Babel, use the plugin "transform-es2015-modules-commonjs" or "preset-es2015" and use ES6 modules instead. 由于您已经在使用Babel,请使用插件“ transform-es2015-modules-commonjs”或“ preset-es2015”并使用ES6模块。
Hope this cleared your doubts! 希望这消除了您的疑虑!
(Btw, it's "receive", not "recieve" ;) (顺便说一句,它是“接收”,而不是“接收”;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.