Dojo AMD 加载程序是不是确保模块只执行一次?

Posted

技术标签:

【中文标题】Dojo AMD 加载程序是不是确保模块只执行一次?【英文标题】:Does Dojo AMD loader ensure modules are executed only once?Dojo AMD 加载程序是否确保模块只执行一次? 【发布时间】:2013-06-13 09:16:53 【问题描述】:

在一些现有的基于 Dojo 的应用程序中,我看到一个使用单例模式的模块:

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

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

我对AMD loader的理解是,通过调用“require”或“define”获取模块时,会检查模块是否已经被加载。如果还没有加载,就会加载JS,执行传递给“define”的函数,内部存储返回值。如果它已经被加载,它将简单地返回之前存储的值。

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

谢谢。

【问题讨论】:

您的假设是正确的,该代码假设主体可能会再次运行,这是完全错误的。请问你在哪里看到的,如果它是在 dojo/dijit 代码中,而不是如果它是你自己的/生产代码当然。 不,那不是 Dojo/Dijit 代码,它是某个同事编写的基于 dojo 的应用程序。我会让他知道他的代码是多余的,非常感谢您的确认。 【参考方案1】:

在某种程度上你是对的,但不完全是

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);
);

【讨论】:

谢谢,我认为您的回答在某种程度上证实了我的假设。您提供的小部件示例没有显示任何“模块单例”行为,并且无法使用的用法示例仅仅是因为它是使用类的错误方式,并且与 AMD 加载器完全无关。 在您的示例中,单例与 AMD 无关。因为单例只确保类有一个实例,而 AMD 确保类只定义一次,模块加载一次。 我的意思是,AMD 提供了一种定义单例的方法,比没有它时更简单:由于模块只执行一次,因此无需添加检查代码。这就是我最初的问题与 AMD 的关系。请注意,AMD 可用于定义对象,而不仅仅是类。

以上是关于Dojo AMD 加载程序是不是确保模块只执行一次?的主要内容,如果未能解决你的问题,请参考以下文章

如何从AMD dojo创建构建

如何在 Dojo AMD 中包含遗留模块

dojo 1.7 AMD 框架有啥好处?

Dojo:覆盖预加载模块

RequireJS 订单插件和 Dojo 1.7.1

AMD/Dojo 1.7 单页应用程序:将 Require() 放在哪里?