4

つまりね:

CommonJSの方法でモバイル(iPhone / Android)アプリケーションをモジュール化しています。そこに驚きはありません。しかし、頭を動かすことができないことが1つあります。

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

1 に答える 1

9

私も Appcelerator Titanium の CommonJS モジュールを使用してモバイル アプリを構築しています。循環依存の問題を解決するために私がしたことは、A と B が 2 つの循環依存モジュールである場合、B では require(A) であり、実際に使用する必要がある直前にその逆の場合です。私の場合、特定のボタンがクリックされたときにのみ B 内に A が必要だったので、ボタンのクリック イベント リスナー内の B に require(A) を配置しました。それが役立つことを願っています。

于 2012-06-24T11:25:41.327 に答える