2013-06-13 27 views
4

在一些现有的基于Dojo的应用程序,我现在用的是形式的单例模式看到一个模块:Dojo AMD loader确保模块只执行一次?

define([...], function(...) { 
    var MyClass = declare(...); 
    if (!_instance) { 
    var _instance = new MyClass(); 
    } 
    return _instance; 
}); 

但是,如果我理解正确的AMD,则不需要_instance的使用,因为函数传递给define(...)调用应该只执行一次...或者可能不是?

我对AMD加载器的理解是,当通过调用“require”或“define”来获取模块时,它会检查模块是否已经加载。如果尚未加载,它将加载JS,执行传递给“define”的函数,并在内部存储返回的值。如果它已经被加载,它将简单地返回先前存储的值。

我的假设是否正确?如果是这样,在编写模块时,我们可以安全地假设给定的模块只会被加载和执行一次,并且我们不需要执行任何检查以查看是否已经初始化某个模块,从而使代码更简单。

谢谢。

+1

你的假设是正确的,该代码假定的身体可能再次运行,这是完全错误的。我可以问你在哪里看到这个,如果它是在dojo/dijit代码中,而不是当然是你自己的/生产代码。 –

+0

不,这不是Dojo/Dijit代码,它是由同事编写的一些基于dojo的应用程序。我会让他知道他的代码是多余的,非常感谢你的确认。 –

回答

3

你是对我的一种方式,但不是完全

define("my.widget", [ "dojo/_base/declare",.... ], function(declare, ...){ 
    return declare("my.widget", [ .. ], { 
     value : "myvalue" 
    }); 
}); 

这里我们定义模块定义类,因此类声明(构造函数)是需要模块时缓存,意思等级只定义一次。但是这并不意味着你可以将它用作静态的,因为这只是类声明,而不是实例。

这是行不通的:

require(["my.widget"], function(widget) { 
    console.log(widget.value); 
}); 

下面是正确的用法:

require(["my.widget"], function(widget) { 
    console.log(new widget().value); 
}); 
+1

谢谢,我认为你的答案以某种方式证实了我的假设。您提供的小部件示例没有显示任何“模块单例”行为,并且不起作用的使用示例仅仅是因为它是使用类的错误方式,并且与AMD加载程序完全无关。 –

+0

在你的例子中,单例与AMD无关。由于singleton只确保类有一个实例,AMD确保类只定义一次,而模块只加载一次。 – Marius

+1

我的观点是,AMD提供了一种比没有它更简单的方式定义单例的方法:因为模块只执行一次,所以不需要添加检查代码。这就是我最初的问题与AMD有关的问题。请注意,AMD可以用来定义对象,而不仅仅是类。 –