Взаимный импорт модулей кода 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 в нижнюю часть этих файлов.

Другие вопросы по тегам