2

Firefox アドオンに JavaScript コード モジュールを使用しているときに、この奇妙な動作に遭遇しました。これがバグなのか、相互インポートを行う悪い設計なのかはわかりません。

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() は外部から呼び出されます。上記のコードで、b から 'c' の undefined をヒットしました。

A init
B init
Error C init : c is undefined

いくつかのトラブルシューティングの後、これを修正するには、

  • a.js内のインポートを交換できます(bはcの前にインポートされます)
  • または、相互インポートを削除できます (c 内から b のインポートを削除します)。これらのいずれかを使用すると、うまくいきます。

私の実際のコードでは、 b と c はいくつかの UI 関連のものを表し、相互に依存しています。モジュールの相互インポートを完全に取り除き、そのうちの 1 つのコールバック関数を登録できます。しかし、この動作の原因を知りたいです。私が理解している限り、ドキュメントにはモジュール間のインポートに関する厳密なガイドラインはありません。また、モジュールのキャッシングにより、 1 つのモジュールを複数回インポートすると共有されることも認識しています。しかし、どういうわけかこれを説明することはできません。ここで何が間違っていますか?

4

1 に答える 1

1

何が起こっているのかについての理論がありますが、確認するためにデバッガーでコードを実行しようとはしていません:

  • a.js が実行され、c.js がインポートされます
  • c.js が実行され、b.js がインポートされます (beforecが定義されています!)
  • b.js は c.js を実行してインポートします。ただし、c.js は以前に一度インポートされているため、再度実行されることはありません。
  • c.jscスコープではまだ定義されていないため (まだ実行を継続していないため、 2 行目の呼び出しが戻るc.jsのをまだ待っているため)、 b.js スコープに挿入されます。importc = undefined
  • b.js の実行が終了します。
  • c.js の実行が終了します。
  • a.js の実行が終了します。

したがって、b.js は の有効なバインディングを受け取ることはなくcb.init()にアクセスしようとすると例外がスローされますc.foo

この理論が正しければ、b.js と c.js の import 呼び出しをこれらのファイルの下部に移動することで、エラーを修正できると思います。

于 2014-02-12T01:35:49.983 に答える