Reputation: 753
I came across this strange behavior while using javascript code modules for a firefox addon. 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.
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() is called externally. Now with the above code, I hit an undefined for 'c' from b.
A init
B init
Error C init : c is undefined
After some troubleshooting, I realized that to correct this,
In my actual code b and c represent some UI related stuff and they have mutual dependencies. 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 ?
Upvotes: 2
Views: 288
Reputation: 604
I have a theory about what is happening, though I haven't tried running the code in a debugger to make sure:
c
is defined!)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.So b.js never receives a valid binding for c
, and b.init()
throws an exception when it tries to access 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.
Upvotes: 1