2013-06-13 28 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可以用來定義對象,而不僅僅是類。 –