Titanium Appcelerator和CommonJS模块(缓存和循环引用)

Titanium Appcelerator和CommonJS模块(缓存和循环引用),titanium,appcelerator,circular-reference,commonjs,Titanium,Appcelerator,Circular Reference,Commonjs,事情是这样的: 我正在使用CommonJS方法使我的移动(iPhone/Android)应用程序模块化。这并不奇怪。但有一件事我就是想不起来 CommonJS允许我创建静态私有变量,这让我可以轻松地创建单例。我认为这至少是因为获取require()d的文件的内容只读取一次,然后每次都返回exports对象(只初始化一次) 但是,当我创建如下所示的循环引用时,每次都会执行包含模块中的代码 等待… 有趣的是,当我写这个问题时,我突然意识到对require()的调用都没有在下一个调用开始之前完成(因此

事情是这样的:

我正在使用CommonJS方法使我的移动(iPhone/Android)应用程序模块化。这并不奇怪。但有一件事我就是想不起来

CommonJS允许我创建静态私有变量,这让我可以轻松地创建单例。我认为这至少是因为获取
require()
d的文件的内容只读取一次,然后每次都返回exports对象(只初始化一次)

但是,当我创建如下所示的循环引用时,每次都会执行包含模块中的代码

等待… 有趣的是,当我写这个问题时,我突然意识到对
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;
I
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');
require('Banana');
require('Pineapple');
Pinapple.js

require('Banana');
require('Banana');
require('Pineapple');
Banana.js

require('Banana');
require('Banana');
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)

我也在使用Appcelerator Titanium中的CommonJS模块来构建一个移动应用程序。我解决循环依赖问题的方法是:如果A和B是两个循环依赖的模块,那么在实际需要使用它之前,B中需要(A),反之亦然。在我的例子中,只有当某个按钮被点击时,我才需要B中的A,所以我在按钮的点击事件监听器中的B中放了一个require(A)。希望能有所帮助。

非常感谢,这节省了很多时间。