Взаимный импорт модулей кода Javascript [Firefox addon]
Я столкнулся с этим странным поведением, когда использовал модули кода JavaScript для аддона Firefox. Я не уверен, является ли это ошибкой или плохим дизайном, делающим взаимный импорт.
Допустим, есть 3 модуля a, b и c.
a.js
var EXPORTED_SYMBOLS = ["a"];
Components.utils.import("resource://mymodule/c.js");
Components.utils.import("resource://mymodule/b.js");
var a = {
init: function() {
dump("A init\n");
b.init();
}
};
b.js
var EXPORTED_SYMBOLS = ["b"];
Components.utils.import("resource://mymodule/c.js");
var b = {
init : function() {
try {
dump("B init\n");
dump(c.foo() + "\n");
} catch (e) {
dump("Error C init : " + e.message + "\n");
}
}
};
c.js
var EXPORTED_SYMBOLS = ["c"];
Components.utils.import("resource://mymodule/b.js");
var c = {
foo : function() {
return "C Foo";
},
};
a.init () вызывается извне. Теперь с приведенным выше кодом, я нажал неопределенный для 'c' от b.
A init
B init
Error C init : c is undefined
После некоторого устранения неполадок, я понял, что исправить это,
- Я могу поменять местами импорт внутри a.js (b импортируется до c)
- Или я могу удалить взаимный импорт (удалить импорт b изнутри c). С любым из них все идет хорошо.
В моем настоящем коде b и c представляют некоторые вещи, связанные с пользовательским интерфейсом, и они имеют взаимозависимости. Я могу полностью избавиться от взаимного импорта модулей и зарегистрировать функцию обратного вызова для одного из них. Но я хочу знать, что вызывает такое поведение. Насколько я понимаю, в документации нет строгих инструкций по импорту между модулями. Мне также известно, что один модуль при импорте несколько раз будет использоваться совместно из-за кэширования модулей. Но как-то не могу объяснить это. Что я здесь не так делаю?
1 ответ
У меня есть теория о том, что происходит, хотя я не пытался запустить код в отладчике, чтобы убедиться:
- a.js запускает и импортирует c.js
- c.js запускает и импортирует b.js (до
c
определено!) - b.js запускает и импортирует c.js. Но c.js больше не запускается, потому что он уже был импортирован ранее.
- поскольку
c
все еще не определено в области видимости c.js (потому чтоc.js
еще не продолжил работу; он все еще ждетimport
позвоните по второй линии, чтобы вернуться),c = undefined
вводится в область действия b.js. - b.js заканчивает выполнение.
- c.js заканчивает выполнение.
- a.js заканчивает выполнение
Таким образом, b.js никогда не получает действительной привязки для c
, а также b.init()
выдает исключение при попытке доступа c.foo
,
Если эта теория верна, я думаю, вы могли бы исправить ошибку, переместив вызовы импорта в b.js и c.js в нижнюю часть этих файлов.