[英]Shall I always invoke either JQuery Deferred.resolve or Deferred.reject?
因此,如下面的代碼所示,它僅處理ajax調用成功的情況,如果ajax調用失敗,則將其忽略,並且永遠不會調用deferred.reject()。 因此,如果遇到失敗的情況,jQuery內是否會永久保留任何事件偵聽器,從而導致內存泄漏?
$.when(loadSomething).done(function() {
// ...
});
function loadSomething() {
var deferred = $.Deferred();
// Only deal with the success case,
// If the ajax call failed, it is ignored and the deferred.reject() will never be invoked.
// So if we meet the failed case, will there any event listener inside jQuery will be keeped
// forever?
ajaxCallToLoad(onResult);
function onResult() {
deferred.resolve();
}
return deferred.promise();
}
為了回答您的真實問題,只有在您維護對延遲和/或promise的引用時,才泄漏內存,無論您是否解析或拒絕延遲。 如果沒有引用,那么它將像平常一樣被垃圾收集。
就是說,我認為在這種情況下,您應該使用.then
方法來轉換/過濾結果,而不是手動構造Deferred。 對於本示例,讓我們創建一個稱為load
的方法,該方法只是隨機解析或拒絕延遲的方法,類似於可能失敗的ajax請求。
function load() {
return $.Deferred(function( dfr ) {
if ( Date.now() % 2 ) {
dfr.resolve( 1 );
}
else {
dfr.reject( "OHNO!" );
}
}).promise();
}
您現在可以使用.then對其進行過濾,如下所示:
var filteredResult = load().then(function( result ) {
return result * 2;
});
現在, filteredResult
是一個承諾,如果解決了加載問題,它將使原始結果加倍,因此filterResult.done( console.log.bind( console ) )
將向控制台顯示2
。 如果加載失敗/被拒絕,則失敗處理程序仍將正常工作。
因此,如果遇到失敗的情況,jQuery內是否會永久保留任何事件偵聽器,從而導致內存泄漏?
幾乎可以肯定。
但是,如果這樣做,則顯式地使用了Promise語義,但隨后違反了Promise合同。 那是不好的做法。 您必須具有“最佳做法”選項:
繼續使用承諾,但要遵守合同。 更新ajaxCallToLoad
以便它也通知您失敗,並在發生延遲時對您的延遲調用reject
。 (如果ajaxCallToLoad
使用的是jQuery的$.ajax
函數,則可以只使用$.ajax
返回的jqXHR
對象;它實現Promise
。)
如果您不想履行承諾合同,只需使用常規的“成功”回調而不是承諾即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.