这就是事情:
我正在使用CommonJS方式使我的移动(iPhone / Android)应用程序模块化。这并不奇怪。但有一点我无法理解。
CommonJS让我创建了STATIC私有变量,这让我可以轻松创建单例。至少,我认为这是因为获取require()
d的文件的内容只读取一次,然后每次都返回导出对象(只初始化一次)。
但是当我创建如下所示的循环引用时,每次都会执行包含模块内的代码。
等待...
有趣的是,在我写这个问题的时候,我突然意识到require()
在下一个问题开始之前没有完成任何调用(因此下面会出现堆栈溢出)。
关于我是否正常的任何想法?这是凌晨5点过来的,所以所有的赌注都是我所关注的:D。
实施例
看到这段代码,它定义了一个单例:
/* Singleton.js */
exports.getSingleton = getSingleton;
function getSingleton(name) {
if (!instance) {
instance = new Thing(name);
}
return instance;
}
function Thing(name) {
this.name = name;
}
var instance;
我require()
这样的文件:
var theFirstThing = require('Singleton').getSingleton('first');
Ti.API.info('first: ' + theFirstThing.name)
var possiblyAnotherOtherThing = require('Singleton').getSingleton('second');
Ti.API.info('second: ' + possiblyAnotherOtherThing.name);
输出是:
[DEBUG] loading: /path/to/sim/MyApp.app/app.js, resource: app_js
[DEBUG] loading: /path/to/sim/MyApp.app/Singleton.js, resource: Singleton_js
[INFO] first: first
[INFO] second: first
为什么以下循环引用不起作用? (如果你愿意的话,我可能已经对自己进行过分析,对其进行评论/回答。)
app.js
require('Banana');
Pinapple.js
require('Banana');
Banana.js
require('Pineapple');
因为输出是这样的:
[DEBUG] loading: /path/to/simulator/MyApp.app/app.js, resource: app_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Banana.js, resource: Banana_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Pineapple.js, resource: Pineapple_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Banana.js, resource: Banana_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Pineapple.js, resource: Pineapple_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Banana.js, resource: Banana_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Pineapple.js, resource: Pineapple_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Banana.js, resource: Banana_js
/* etcetera (total of 15 times back and forth) */
[DEBUG] loading: /path/to/simulator/MyApp.app/Pineapple.js, resource: Pineapple_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Banana.js, resource: Banana_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Pineapple.js, resource: Pineapple_js
[ERROR] Script Error = Maximum call stack size exceeded. (unknown file)
答案 0 :(得分:9)
我也在使用Appcelerator Titanium中的CommonJS模块来构建移动应用程序。我为解决循环依赖问题所做的是:如果A和B是2个循环相关的模块,在实际需要使用它之前需要(A)在B中,反之亦然 。在我的情况下,我只在单击某个按钮时才需要A内部B,所以我在按钮的click事件监听器中放入了一个require(A)。希望有所帮助。