Appcelerator和CommonJS模块(缓存和循环引用)。[英] Appcelerator and CommonJS modules (caching and circular references)

本文是小编为大家收集整理的关于Appcelerator和CommonJS模块(缓存和循环引用)。的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

这是:

我正在使用使我的移动(iPhone/android)应用模块化的通用方式模块化.那里不足为奇.但是有一件事我只是无法转过头.

commonj允许我创建静态私人变量,这使我可以轻松地创建单例.我认为,至少这是因为仅读取require() d的文件的内容一次,然后每次返回导出对象(仅初始化一次).

但是,当我创建一个如下所示的循环引用时,每次执行随附的模块内部的代码.

等等... 有趣的是,当我写这个问题时,我突然意识到在下一个开始之前,没有任何呼叫require()完成(因此,下面显示的堆栈溢出).

对我是否正轨有任何想法吗?在这里过去的五点,所以就我而言,所有赌注都关闭了: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');

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)

推荐答案

我也正在使用Appcelerator Titanium中的CommonJS模块来构建移动应用程序.我为解决循环依赖性问题所做的工作是:如果a和b是2个循环依赖性模块,则在B中需要(a),而在您实际需要使用它之前,vice-vice-vice-vice-vice-vice-vice-vice-vice-c. .就我而言,只有在单击某个按钮时,我才需要一个内部B,因此我在按钮的单击事件侦听器中将airpe(a)放入B中.希望会有所帮助.

本文地址:https://www.itbaoku.cn/post/1938168.html

问题描述

Here's the thing:

I'm using the CommonJS way of making my mobile (iPhone/Android) application modular. No surprise there. But there's one thing that I just can't get my head around.

CommonJS lets me create STATIC private variables, which lets me create singletons at ease. This, I think at least, is because the contents of a file that gets require()d is read only once and then the exports object (which is initialized only once) is returned every time.

But when I create a circular reference as seen below, the code inside the included module is executed every time.

Wait... Funny thing is, while I'm writing this question, I suddenly realise that none of the calls to require() finish before the next one starts (hence the stack overflow demonstrated below).

Any thoughts on whether I'm on track or not? It's past 5 AM over here, so all bets are off as far as I'm concerned :D.

EXAMPLES:

See this piece of code, it defines a singleton:

/* 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() this file as such:

var theFirstThing = require('Singleton').getSingleton('first');
Ti.API.info('first: ' + theFirstThing.name)

var possiblyAnotherOtherThing = require('Singleton').getSingleton('second');
Ti.API.info('second: ' + possiblyAnotherOtherThing.name);

The Output is:

[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

Why is it then that circular references like the following don't work? (I might have already ansered this myself, comment/answer on it if you like).

app.js

require('Banana');

Pinapple.js

require('Banana');

Banana.js

require('Pineapple');

Because the output is this:

[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)

推荐答案

I too am using CommonJS modules in Appcelerator Titanium to build a mobile app. What I did to resolve the circular dependency problem was this: if A and B are the 2 circularly-dependent modules, require(A) in B, and vice-versa just before you actually need to use it. In my case, I needed A inside B only when a certain button got clicked, so I put a require(A) in B inside the button's click event listener. Hope that helps.