简体   繁体   English

Javascript代码模块相互导入[Firefox插件]

[英]Javascript code modules mutual import [Firefox addon]

I came across this strange behavior while using javascript code modules for a firefox addon. 我在将javascript代码模块用于Firefox插件时遇到了这种奇怪的行为。 I'm not sure if this is a bug or a bad design doing mutual imports. 我不确定这是错误还是相互导入的不良设计。

So let's say there are 3 modules a, b and c. 假设有3个模块a,b和c。

a.js 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 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 c.js

var EXPORTED_SYMBOLS = ["c"];
Components.utils.import("resource://mymodule/b.js");

var c = {
    foo : function() {
        return "C Foo";
    },
};

a.init() is called externally. a.init()在外部被调用。 Now with the above code, I hit an undefined for 'c' from b. 现在,使用上面的代码,我从b命中了一个未定义的'c'。

A init
B init
Error C init : c is undefined

After some troubleshooting, I realized that to correct this, 经过一些故障排除后,我意识到可以解决此问题,

  • I can either swap the imports inside a.js (b is imported before c) 我可以在a.js中交换导入(b在c之前导入)
  • Or I can remove the mutual import ( remove the import of b from within c) With either of these, things go fine. 或者,我可以删除相互导入(从c内删除b的导入)借助以上两种方法,一切都会顺利进行。

In my actual code b and c represent some UI related stuff and they have mutual dependencies. 在我的实际代码中,b和c代表一些与UI相关的东西,它们具有相互依赖性。 I can totally get rid of a mutual import of modules, and register a callback function for one of them. 我完全可以摆脱模块的相互导入,并为其中一个模块注册一个回调函数。 But I wish to know what is causing this behavior. 但是我想知道是什么导致了这种行为。 As far as I understand the documentation do not have any strict guidelines for import among modules. 据我了解, 该文档对模块之间的导入没有严格的指导。 I am also aware that one module when imported multiple times will be shared because of caching of modules. 我也知道,由于模块的缓存, 一次导入多个模块将被共享 But somehow can't explain this. 但是以某种方式无法解释这一点。 What am I doing wrong here ? 我在这里做错了什么?

I have a theory about what is happening, though I haven't tried running the code in a debugger to make sure: 我有一个关于正在发生的事情的理论,尽管我没有尝试在调试器中运行代码来确保:

  • a.js runs and imports c.js a.js运行并导入c.js
  • c.js runs and imports b.js (before c is defined!) c.js运行并导入b.js(在定义c之前!)
  • b.js runs and imports c.js. b.js运行并导入c.js。 But c.js does not run again, because it has already been imported once before. 但c.js 不会再次运行,因为它已经过一次进口。
  • Since c is still undefined in the c.js scope (because c.js has not continued running yet; it is still waiting for the import call on line 2 to return), c = undefined is injected into the b.js scope. 由于c在c.js范围内仍未定义(因为c.js尚未继续运行;它仍在等待第2行上的import调用返回),因此c = undefined将注入b.js范围。
  • b.js finishes executing. b.js完成执行。
  • c.js finishes executing. c.js完成执行。
  • a.js finishes executing. a.js完成执行。

So b.js never receives a valid binding for c , and b.init() throws an exception when it tries to access c.foo . 因此,b.js永远不会收到对c的有效绑定,并且b.init()在尝试访问c.foo时会引发异常。

If this theory is correct, I think you could fix the error by moving the import calls in b.js and c.js to the bottoms of those files. 如果该理论正确,我认为您可以通过将b.js和c.js中的import调用移到那些文件的底部来解决错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM