不解决延迟会不会造成内存泄漏?
Will not resolving a deferred create memory leaks?
假设如下代码:
var deferred = $.Deferred();
deferred.done(function(){
// do something with events, references to dom, etc...
});
deferred.fail(function(){
// do something with events, references to dom, etc...
});
如果我永远不会调用 resolve()
或 fail()
,这是否会导致内存泄漏,因为我在回调中保留了引用?
如果我调用一个而不调用另一个,另一个会被垃圾回收吗?所以如果我调用 fail()
,jquery 会摆脱 done()
吗?
我可能完全想错了,但我想澄清一下。到目前为止,我发现的最接近的是 Shall I always invoke either JQuery Deferred.resolve or Deferred.reject?。但是用例有点不同,因为在那个例子中,用户从未为 fail()
.
定义回调
我也遇到过这个,Can jQuery deferreds be cancelled?,但是我并没有尝试取消 deferred
。
我知道这不是最佳做法,但出于问题的目的,我仍然很好奇它是否会导致内存问题。
谢谢,
If I never end up calling resolve() or fail(), will this cause memory
leaks, since I keep references in the callbacks?
如果 deferred
变量本身不再可以通过任何代码访问(这也意味着没有其他承诺依赖于此代码),那么它将有资格进行垃圾收集,即使它是从未解决或拒绝。如果您想更详细地了解 "reachable" 的含义,那么您最好展示您关心的实际代码。
另一方面,如果您仍然在某个地方持有 deferred
变量,或者仍然可以访问的其他承诺取决于此承诺(这意味着这些承诺引用了此承诺) , 那么无论延迟对象是否已经被解析,它仍然是活着的,不能被垃圾收集。
Promise 在垃圾回收时只是普通的 Javascript 对象,因此它们遵循与普通对象相同的所有垃圾回收规则。
If I call one, but not the other, will the other be garbage collected?
So if I call fail(), will jquery get rid of done().
代码本身不会被垃圾回收。垃圾收集的是变量和对象的内容。因此,在您显示的代码中,垃圾收集的主题是 deferred
变量(变量指向的承诺对象)的内容。而且,正如我上面所说的,无论您已经解决、拒绝还是两者都没有,都没有区别。重要的是您的代码是否仍然可以访问该对象。如果任何代码仍然可以访问 deferred
变量,或者如果任何其他代码或承诺仍然可以访问此承诺。
举个例子,如果我的页面中有这个顶级代码:
<script>
var deferred = $.Deferred();
deferred.done(function(){
// do something with events, references to dom, etc...
});
deferred.resolve();
</script>
deferred
变量仍然可以访问并且仍然存在,因此它指向的 Deferred 对象无法被垃圾回收。
或者,如果我有这个:
<script>
$("#submit").click(function() {
var p = $.get(myURL);
p.done(function(data) {
if (data) {
$("#msg").html(data.msg);
}
});
});
</script>
然后,一旦 ajax 调用完成并调用 .done()
处理程序,就不再有任何代码可以访问 p
变量的实例,因为ajax 操作已完成,因此它将释放对 promise 的引用,因此它不能再触发任何更多的 promise 回调本身。而且,它已经超出了点击处理程序回调函数的范围,并且没有仍然可以访问 p
的实时事件处理程序,因此它变得无法访问。届时,它将有资格进行垃圾回收。
假设如下代码:
var deferred = $.Deferred();
deferred.done(function(){
// do something with events, references to dom, etc...
});
deferred.fail(function(){
// do something with events, references to dom, etc...
});
如果我永远不会调用
resolve()
或fail()
,这是否会导致内存泄漏,因为我在回调中保留了引用?如果我调用一个而不调用另一个,另一个会被垃圾回收吗?所以如果我调用
fail()
,jquery 会摆脱done()
吗?
我可能完全想错了,但我想澄清一下。到目前为止,我发现的最接近的是 Shall I always invoke either JQuery Deferred.resolve or Deferred.reject?。但是用例有点不同,因为在那个例子中,用户从未为 fail()
.
我也遇到过这个,Can jQuery deferreds be cancelled?,但是我并没有尝试取消 deferred
。
我知道这不是最佳做法,但出于问题的目的,我仍然很好奇它是否会导致内存问题。
谢谢,
If I never end up calling resolve() or fail(), will this cause memory leaks, since I keep references in the callbacks?
如果 deferred
变量本身不再可以通过任何代码访问(这也意味着没有其他承诺依赖于此代码),那么它将有资格进行垃圾收集,即使它是从未解决或拒绝。如果您想更详细地了解 "reachable" 的含义,那么您最好展示您关心的实际代码。
另一方面,如果您仍然在某个地方持有 deferred
变量,或者仍然可以访问的其他承诺取决于此承诺(这意味着这些承诺引用了此承诺) , 那么无论延迟对象是否已经被解析,它仍然是活着的,不能被垃圾收集。
Promise 在垃圾回收时只是普通的 Javascript 对象,因此它们遵循与普通对象相同的所有垃圾回收规则。
If I call one, but not the other, will the other be garbage collected? So if I call fail(), will jquery get rid of done().
代码本身不会被垃圾回收。垃圾收集的是变量和对象的内容。因此,在您显示的代码中,垃圾收集的主题是 deferred
变量(变量指向的承诺对象)的内容。而且,正如我上面所说的,无论您已经解决、拒绝还是两者都没有,都没有区别。重要的是您的代码是否仍然可以访问该对象。如果任何代码仍然可以访问 deferred
变量,或者如果任何其他代码或承诺仍然可以访问此承诺。
举个例子,如果我的页面中有这个顶级代码:
<script>
var deferred = $.Deferred();
deferred.done(function(){
// do something with events, references to dom, etc...
});
deferred.resolve();
</script>
deferred
变量仍然可以访问并且仍然存在,因此它指向的 Deferred 对象无法被垃圾回收。
或者,如果我有这个:
<script>
$("#submit").click(function() {
var p = $.get(myURL);
p.done(function(data) {
if (data) {
$("#msg").html(data.msg);
}
});
});
</script>
然后,一旦 ajax 调用完成并调用 .done()
处理程序,就不再有任何代码可以访问 p
变量的实例,因为ajax 操作已完成,因此它将释放对 promise 的引用,因此它不能再触发任何更多的 promise 回调本身。而且,它已经超出了点击处理程序回调函数的范围,并且没有仍然可以访问 p
的实时事件处理程序,因此它变得无法访问。届时,它将有资格进行垃圾回收。