Reputation: 5864
I want to make a simple singleton using RequireJS.
Something like this:
// js/modules/singleton.js
define([], function () {
var Singleton = function() {
this.value = 10;
}
return new Singleton();
});
In my main entry I have the following code:
// main.js
require.config({
paths: {
singleton: 'js/modules/singleton'
},
shim: {
}
});
var o1 = require(["singleton"]);
var o2 = require(["singleton"]);
console.log(o1 === o2); // true
console.log(o1.value); // undefined (?!)
console.log(o2.value); // undefined (?!)
o1.value = 20;
console.log(o1.value); // 20
console.log(o2.value); // 20
o2.value = 30;
console.log(o1.value); // 30
console.log(o2.value); // 30
Variables o1 and o2 were correctly pointing to the same singleton instance (o1 === o2), but why are o1.value and o2.value undefined??
I would expect the attribute "value" to be =10 at this like, since it was so initialized.
Upvotes: 0
Views: 804
Reputation: 74076
Your problem is pretty much a race condition.
A simple (synchronous!) call like
var o1 = require(["singleton"]);
returns the module just, if it has previously loaded using the asynchronous version of require()
.
So to solve your problem, just wrap your code in a async require()
call like this:
require( ['singleton'], function( singleton ){
o1 = singleton;
o2 = singleton;
console.log(o1 === o2); // true
console.log(o1.value); // 10
console.log(o2.value); // 10
o1.value = 20;
console.log(o1.value); // 20
console.log(o2.value); // 20
o2.value = 30;
console.log(o1.value); // 30
console.log(o2.value); // 30
});
Citing the RequireJS documentation (highlighting added):
Console debugging: If you need to work with a module you already loaded via a
require(["module/name"], function(){})
call in the JavaScript console, then you can use the require() form that just uses the string name of the module to fetch it:
require("module/name").callSomeFunction()
Note this only works if "module/name" was previously loaded via the async version of require:
require(["module/name"])
. If using a relative path, like './module/name', those only work inside define
Upvotes: 1