[英]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.