将requireJS模块用作单例是不好的做法吗?

时间:2012-03-16 07:01:36

标签: javascript requirejs

我打算使用以下模式来使用基于requireJS的模块作为单例。请注意, classA 会返回类型为“classA”的实例,而其他类 classB,classC和main 会从模块返回类的类型。所有这些都是基于MooTools类的类。

我们的想法是使用 classA 作为全局可用的单例,这些方法只是填充程序。如果这是一个可以使用的模式,是否有任何想法?

这会在稍后阶段回来咬我吗?我还没试过在项目上运行r.js,所以我有点担心,并寻找一些建议。

    // classA.js
    define([], function() {
        var classA = new Class({

            initialize: function (regionId) {
                // perform some Initialization.
                this.data = null;
            },

            doSomething: function(param) {
                // some thing.
                this.data = param;
            }
        };

        return new classA();
    });

    // classB.js
    define(["classA"], function(classA) {
        var classB = new Class({

            initialize: function (regionId) {
                // perform some Initialization.
            },

            doSomethingElse: function() {
                // some thing.
                classA.doSomething("Go back to Work Now!");
            }
        };

        return classB;
    });


    // classC.js
    define(["classA"], function(classA) {
        var classB = new Class({

            initialize: function (regionId) {
                // perform some Initialization.
            },

            doSomethingElse: function() {
                // some thing.
                classA.doSomething("Time to Play!");
            }
        };

        return classC;
    });


    // main.js
    define(["classA", "classB", "classC"], function(classA, classB, classC) {
        var main = new Class({

            initialize: function (regionId) {
                // perform some Initialization.
                this.b = new classB();
                this.c = new classC();
            },

            doEverything: function() {
                // some thing.
                this.b.doSomethingElse();
                classA.doSomething("Nap Time!");
            }
        };

        return main;
    });

非常感谢...

2 个答案:

答案 0 :(得分:37)

不,我想不出反对使用带有require.js的单身人士的理由。

您的模块定义应导出单例。你这样做的方式很好,因为它是一个单身人,你也可以避免new。我使用像

这样的东西
define(function (require) {
    var singleton = function () {
        return {
            ...
        };
    };
    return singleton();
});

模块的第一个require将加载并导出它。需要你的单身人士的其他一些模块将只重用已经导出的模块。

答案 1 :(得分:7)

  

这会在稍后阶段回来咬我吗?

我从这里开始使用已接受答案的模式,但是我的单页JavaScript应用程序变成了一个主线程和一个web worker,因为它进行了大量的计算并且页面没有响应。

当我将一些模块移动到Web worker中时,出现了奇怪的行为。我花了很多时间来弄明白,但我意识到我的一些requirejs模块(即单身人士)被加载了两次。

我发现如果主线程和modules that run in a web worker中都需要单例模块,则单例模块将在Web worker中第二次加载(因此它不是真的是单身人士)。一个副本位于主线程中,另一个副本位于Web工作线程中。如果您的单件存储变量,则您将拥有两个副本。

这一切都有意义,因为工作者和主线程有单独的地址空间(也许这就是为什么我有一个downvote?)。我在这里发布答案是因为有人可能遇到同样的问题,因为requirejs中没有警告。

解决方案(在我的情况下)不是在主工作线程和Web工作线程之间混合模块。这可能是一个很大的设计约束,在Java或C#等环境中不一定是个问题。