Javascript代码模块相互导入〔Firefox插件〕



我在为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 initn");                                                           
b.init();                                                                   
}                                                                               
};     

b.js

var EXPORTED_SYMBOLS = ["b"];
Components.utils.import("resource://mymodule/c.js");
var b = {
init : function() {
try {
dump("B initn");
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">

A init
B init
Error C init : c is undefined

经过一些故障排除,我意识到要纠正这一点,

  • 我可以交换a.js中的导入(b在c之前导入)
  • 或者我可以删除相互导入(从c中删除b的导入)有了这两个,一切都会好起来

在我的实际代码中,b和c表示一些与UI相关的东西,它们具有相互依赖性。我可以完全取消模块的相互导入,并为其中一个模块注册回调函数。但我想知道是什么导致了这种行为。据我所知,文档中没有任何严格的模块间导入指南。我还知道,一个模块在多次导入时会被共享,因为模块的缓存。但不知怎的无法解释这一点。我在这里做错了什么?

我对正在发生的事情有一个理论,尽管我还没有尝试在调试器中运行代码以确保:

  • a.js运行并导入c.js
  • c.js运行并导入b.js(在定义c之前!)
  • b.js运行并导入c.js。但是c.js不会再次运行,因为它以前已经导入过一次
  • 由于c在c.js作用域中仍然未定义(因为c.js还没有继续运行;它仍在等待第2行的import调用返回),因此c = undefined被注入b.js范围
  • b.js完成执行
  • c.js完成执行
  • .js完成执行

因此b.js从未接收到c的有效绑定,并且b.init()在尝试访问c.foo时抛出异常。

如果这个理论是正确的,我认为您可以通过将b.js和c.js中的导入调用移动到这些文件的底部来修复错误。

相关内容

  • 没有找到相关文章

最新更新