因此,如下面的代码,它只处理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();
}
答案 0 :(得分:0)
要回答您的真实问题,如果您在代码中某处保留对延迟和/或承诺的引用,则只会泄漏内存,无论您是否解决或拒绝延迟。如果没有引用,那么它将像平常一样被垃圾收集。
那就是说,我认为在这种情况下,而不是手动构建Deferred,您应该使用.then
方法允许您转换/过滤结果。为了这个例子,让我们创建一个名为load
的方法,该方法只是随机解析或拒绝延迟,类似于可能失败的ajax请求。
function load() {
return $.Deferred(function( dfr ) {
if ( Date.now() % 2 ) {
dfr.resolve( 1 );
}
else {
dfr.reject( "OHNO!" );
}
}).promise();
}
你现在能够使用它。然后过滤它:
var filteredResult = load().then(function( result ) {
return result * 2;
});
filteredResult
现在是一个承诺,如果解决了加载,它会使原始结果加倍,因此filterResult.done( console.log.bind( console ) )
会将2
打印到控制台。如果负载失败/被拒绝,那么失败处理程序仍然可以正常工作。
答案 1 :(得分:0)
因此,如果我们遇到失败的情况,jQuery中是否会有任何事件监听器永远会导致内存泄漏?
几乎肯定不会。
但是,如果你这样做,你明确地使用了承诺语义,但随后违反了承诺合同。那是不好的做法。你必须选择“最佳实践”:
继续使用承诺,但坚持合同。更新ajaxCallToLoad
以便它也会通知您失败,并在发生这种情况时致电reject
。 (如果ajaxCallToLoad
正在使用jQuery的$.ajax
函数,则可以使用jqXHR
返回的$.ajax
对象;它实现Promise
。)
如果您不想履行承诺合同,只需使用正常的“成功”回调而不是承诺。