1

I'm creating a Javascript project using the latest RequireJS. I'm defining a chessWorker module like so:

var worker;

define("chessWorker", ["jquery", "messageListener"], function($, listener) {
    if (worker) {
        return worker;
    } else {
        $.ajax({
            url: "...",
            success: function(data) {
                worker = new Worker(window.URL.createObjectURL(new window.Blob([data])));

                worker.onmessage = listener

                worker.error = function(e) {
                    ...
                };

                return worker;
            }
        });
    }
});

Is this bad practice? If so, how should I define this otherwise? Are there any standards concerning singletons on how they should be defined?

Martijn
  • 2,268
  • 3
  • 25
  • 51

1 Answers1

2

Defining worker as a global is not really recommended you should use a closure instead:

define(function(){
    var instance = null;

    function MySingleton(){
        if(instance !== null){
            throw new Error("Cannot instantiate more than one MySingleton, use MySingleton.getInstance()");
        } 

        this.initialize();
    }
    MySingleton.prototype = {
        initialize: function(){
            // summary:
            //      Initializes the singleton.

            this.foo = 0;
            this.bar = 1;
        }
    };
    MySingleton.getInstance = function(){
        // summary:
        //      Gets an instance of the singleton. It is better to use 
        if(instance === null){
            instance = new MySingleton();
        }
        return instance;
    };

    return MySingleton.getInstance();
});

Note: Also make sure your ajax call is synchronous or when you require the chessWorker module you will get null as response.

gon250
  • 3,405
  • 6
  • 44
  • 75
  • I don't get this approach, everytime I need the module the instance is set to null? – Martijn Mar 23 '15 at 14:04
  • When you require `chessWorker` for the first time require.js will execute your module code and remember the return value. The next time you request the module it will not execute the module code again so the line `var instance = null;` will not be executed you can see a demo of the singleton implementation above at http://codepen.io/lagden/pen/ioesL – gon250 Mar 23 '15 at 14:08
  • So does that mean that everything is a singleton then? – Martijn Mar 23 '15 at 14:09
  • No, the module in my is returning `instance` but not directly (return instance) we are using a function to access the variable `return MySingleton.getInstance();` the function has access to `instance` via its scope. This is like that because the existence of closures. If you need to learn more about closures please read http://stackoverflow.com/questions/111102/how-do-javascript-closures-work. – gon250 Mar 23 '15 at 14:12