Appcelerator- und CommonJS-Module (Caching und Zirkelverweise)

Hier ist das Ding:

Ich verwende die CommonJS-Methode, um meine mobile Anwendung (iPhone / Android) modular zu gestalten. Keine Überraschung dort. Aber eines kann ich einfach nicht verstehen.

Mit CommonJS kann ich private STATIC-Variablen erstellen, mit denen ich problemlos Singletons erstellen kann. Das liegt, denke ich zumindest, am Inhalt einer Datei, die abgerufen wirdrequire()d wird nur einmal gelesen und dann wird das Exportobjekt (das nur einmal initialisiert wird) jedes Mal zurückgegeben.

Wenn ich jedoch einen Zirkelverweis wie unten dargestellt erstelle, wird der Code im enthaltenen Modul jedes Mal ausgeführt.

Warten... Komische Sache ist, während ich diese Frage schreibe, merke ich plötzlich, dass keiner der Anrufe zurequire() Beenden Sie den Vorgang, bevor der nächste beginnt (daher der unten gezeigte Stapelüberlauf).

Irgendwelche Gedanken darüber, ob ich auf dem richtigen Weg bin oder nicht? Hier ist es nach 5 Uhr morgens, daher sind alle Wetten für mich ungültig: D.

BEISPIELE

Wenn Sie diesen Code sehen, definiert er einen 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() Diese Datei als solche:

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

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

Die Ausgabe ist:

[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

Warum funktionieren dann Zirkelverweise wie die folgenden nicht? (Ich hätte das vielleicht schon selbst beantwortet, kommentiere / beantworte es, wenn du möchtest).

app.js

require('Banana');

Pinapple.js

require('Banana');

Banana.js

require('Pineapple');

Weil die Ausgabe wie folgt lautet:

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

Antworten auf die Frage(1)

Ihre Antwort auf die Frage