我对Javascript很陌生,而且我遇到了一个我似乎无法理解的问题。控制台抱怨说它没有认识到这个功能。
我有以下代码(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;
以下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;
控制台抛出以下错误,但不太清楚为什么: venture-stock.js:44673未捕获TypeError:GraphActions.recieveGraphData不是函数。
有谁知道为什么会这样?在另一个地方调用了同样的方法没有问题。
在上面的代码中调试代码并评估GraphAction对象时,我得到以下定义的函数不可用的内容:
在其他位置,功能可用:
任何帮助将不胜感激!
答案 0 :(得分:3)
这是因为您的模块之间存在循环引用。模块GraphActions
需要模块StockService
,其中也需要GraphActions
。 StockService
recieveGraphData
方法StockService
实际需要什么并不重要,而需要getGraphData
的方法是require
:模块加载器没有这种级别的代码分析。 GraphActions
将始终返回整个模块,因此它是循环引用。
那么,在这些情况下会发生什么?
模块加载器在加载require('../utils/StockService')
时遇到GraphActions
,然后停止执行StockService
以加载GraphActions
。此时,StockService
的导出属性为...... none。这就是var GraphService = {
getGraphData: function(request) {
...
GraphService.getHistoricStockData(request);
},
recieveGraphData: function(response) { ... },
getHistoricStockData: function(symbol) {
...
GraphService.recieveGraphData(res.body);
}
};
module.exports = GraphService;
中你得到一个空对象的原因。
将两个模块合并为一个,例如
getGraphData
相反,即在两个不同的模块中解耦recieveGraphData
和require
。我不太喜欢这个,因为它会导致过多的模块碎片。
只要使用CommonJS,您就可以在任意位置使用StockService.js
,因此在getHistoricStockData: function(symbol) {
request.post('http://localhost:8080/historicalData')
...
.end(function(err, res) {
...
var GraphActions = require('../actions/GraphActions');
GraphActions.recieveGraphData(res.body);
});
}
中您可以这样做:
GraphActions
现在,由于执行将不立即需要import
,因此稍后当所有依赖项完全加载时,模块将被加载,因此您将获得一个完全正常工作的模块
在ES6中,您不能在根级别之外使用import
,即您无法在函数内使用import * as StockService from '../utils/StockService';
...
export function getGraphData(request) {
...
StockService.getHistoricStockData(request);
};
export function recieveGraphData(response) { ... };
export function test() { ... };
。所以你不能使用带有ES6语法的解决方案C?
实际上开始时并不是必需的,因为CommonJS模块的分辨率与ES6不同,后者更为先进。所以,你已经写过了:
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);
});
};
:
GraphActions.js
那么这里发生了什么?加载import
,达到StockService
语句,模块的执行停止,然后加载StockService
。到目前为止,它与CommonJS相同。
在import
中,加载程序将满足GraphActions
语句,然后执行Function Test{
while($true){
write-host "I want this to refresh every time"
Start-Sleep -Seconds 4
cls
}
}
Write-Host "I want this to be at the screen always"
Test
简历并正确导出整个模块。所以你从ES6开始就是金色的。
这将引导我们
由于您已经在使用Babel,请使用插件" transform-es2015-modules-commonjs"或"预设-es2015"而是使用ES6模块。
希望这清除了你的疑虑!
(顺便说一句,它"收到#34;而不是"收到&#34 ;;)