2014-01-27 48 views
0

我甚至不知道如何解釋這個問題,所以我不得不使用例子。這可能看起來不像是有用的代碼,實際上它不是,但這是我剛剛遇到的一個問題的例子,只是簡單的要領。Javascript:當我創建一個新實例時,舊對象會發生什麼?

讓我們假設我有

function myObject(params) { 

    .. do some time-consuming asynchronous stuff 
     with AJAX and the like ... 

    return (before all the above is completed); 

} 

function myFunction(params) { 

    var doTheSlowStuff = new myObject(params); 

} 

myFunction(firstParams); 
myFunction(moreParams); 

當我做第二個電話會發生什麼到第一myObject的給myFunction()?它是否有機會完成它的工作(如果是的話,它會在什麼時候收集垃圾)?還是在它有機會完成它開始之前被無情地拋棄?

+0

對'myObject'的兩次調用都將完成(即,異步行爲確實會發生兩次)。我不認爲你在這個例子中包含了足夠的信息來確定是否會丟失任何信息,但這很有可能。每次調用'myFunction'都會創建自己的'doTheSlowStuff'變量,所以未來調用不會從另一個調用中銷燬'doTheSlowStuff'。但是,如果該值離開「myFunction」的範圍,則所有投注都將關閉,實際上可能會發生破壞。 – apsillers

+0

您可以從'myObject'返回一個承諾,並在'myFunction'中處理成功。 – elclanrs

回答

0

在此特定實例中,您將創建兩個myObject實例,這些實例將保留在內存中,直到您的應用程序退出。

function myObject(params) { 

    // do something async, like output 
    // every second ... 
    var callback = function() { 
    console.log("I am object " + params); 
    setTimeout(callback, 1000); 
    }; 
    callback(); 

} 

function myFunction(params) { 

    var doTheSlowStuff = new myObject(params); 

} 

myFunction(1); 
myFunction(2); 
// etc. 

看到一個工作示例:http://jsbin.com/osEFuWib/1/edit

+0

'直到您的應用程序退出' 這很有趣。你已經讓我對我的問題進一步闡明。我希望myObject做的是遍歷一個params數組,調用AJAX函數或其他一些函數,這些函數會返回數組中每個值的promise。我不關心myFunction或myObject的返回值。我想避免的是你似乎會建議的事情 - 即使所有異步的東西都完成了,我創建的每個myObject都會保留在內存中。情況是這樣嗎?如果是這樣,我將不得不尋找其他方法。 –

+0

@MarkGreenwood底線是,如果你沒有任何對你的數據的引用,它最終會被垃圾收集。所以沒有什麼特別的理由說明你爲什麼不能*爲你的需要內存的應用程序使用JavaScript。它可能不是這個用例最合適的工具,你可能必須小心以確保你沒有任何泄漏,但是你可以使用JavaScript。只需確保DOM中的任何位置都無法訪問範圍內的數據,包括連接到DOM元素的事件處理程序或全局範圍內的任何東西。觀看我上面鏈接的視頻。 –

+0

@Brian Gordon謝謝,我想這就是我需要知道的。這不是一個飢餓的應用程序(還),這個問題是關於我試圖阻止它成爲如此 - 我沒有說得那麼好。 –

1

所有耗時異步的東西都將異步發生:)

您可以通過運行一些異步測試這種行爲證明了這一點

這意味着異步調用(例如XHR或setTimeout)會立即返回並允許執行繼續。換句話說,myObject構造函數將很快返回,所以在構造兩個myObjects之間不會有任何延遲。在均爲 myFunctions返回後,最終控件將返回到事件循環,並且JavaScript引擎將繼續處理事件,如鼠標單擊,WebSocket事件,計時器(如setTimeout)或返回的XHR請求。直到返回控制事件循環,所以不要做任何瘋狂的喜歡

while(true) { 
    // Check XHR status 
} 

不要擔心垃圾收集你的異步回調將不會執行;如果您的範圍內有myObject的AJAX(XHR)請求等DOM事件,那麼它將不會被垃圾收集,直到事件處理程序本身被垃圾收集爲止。

0

該異步代碼可以訪問回調函數。回調將運行並且是獨立的任何其他對象。 「丟失」對象或創建新對象不會改變這一點。因此,掛起的異步操作必須明確取消,或者必須防止回調在調用時執行不需要的效果。關於JavaScript中對象的事情很簡單:只要包括回調在內的任何代碼都可以訪問該對象(例如分配給範圍內的變量,窗口​​屬性或綁定到DOM),它們保持可用。否則,他們是無法到達,並將在某個時候回收。

+1

要添加的一件事:DOM也可以引用對象並阻止它們被垃圾收集。這裏有一個關於如何發現這些泄漏的優秀演講:https://www.youtube.com/watch?v=x9Jlu_h_Lyw –

+0

@BrianGordon好點。我認爲只能從代碼訪問,但註釋補充說。 – user2864740

相關問題