gpt4 book ai didi

knockout.js - knockout 订阅洞察 : detecting if disposed

转载 作者:行者123 更新时间:2023-12-03 02:59:03 24 4
gpt4 key购买 nike

我的 ko 模型中有一个订阅管理,它通过拦截订阅并保存对它们的引用来保存任何订阅。

然后我 dispose() 它们,但有时我需要了解 sub 是否已经被释放。订阅对象的 bool 值成员 Gb 是事件-非事件标志吗?我发现有时当我处置订阅时,其 Gb 会变为 false,有时不会。我是否必须将此解释为处置失败?

一旦我处理了订阅,订阅对象就准备好被垃圾收集了吗?

编辑:我只需要了解订阅是否已处理,如标题中所述。我以我知道的唯一方式获取订阅,在声明时保存对它的引用:

var mySub = myObservable.subscribe(function(){/*do something*/});

一段时间后,我需要一种方法来确定 mySub 是否已被释放。

function isDisposed(mySubscription) {
// if is disposed return true else return false
}

我需要基于此执行一些逻辑,而不仅仅是在尚未处理它的情况下处理它(或者我可以简单地再次调用处理方法)。是否可以确定订阅处置状态?

最佳答案

关于手动订阅

Knockout 源代码是使用 Google Closure 编译器编译的,因此只有在源代码中显式导出的属性和方法才会出现在编译后的库代码中。

话虽如此,订阅有一个“私有(private)”属性isDispose,但它不会被导出。因此,为订阅导出的唯一 API 是 dispose

源代码一览 - ko.subscription (knockout-3.1.0.debug):

ko.subscription = function (target, callback, disposeCallback) {
this.target = target;
this.callback = callback;
this.disposeCallback = disposeCallback;
this.isDisposed = false;
ko.exportProperty(this, 'dispose', this.dispose);
};
ko.subscription.prototype.dispose = function () {
this.isDisposed = true;
this.disposeCallback();
};

关于内存泄漏和计算

1) 关于计算的一个有趣的事实 - 考虑以下计算

var myObservable1 = ko.observable(true);
var myObservable2 = ko.observable('foo');

var myComputed = ko.computed(function () {
if (myObservable1()) {
return myObservable2() + 'bar';
}
});

在此示例中,myCompulated 有 2 个依赖项。但是,如果我们将 false 赋值给 myObservable1myCompulated 将重新评估,并且在重新评估之后,它只会有 1 个依赖项并订阅 myObservable2 将被处置。

为什么要处置它:

解释在于如何计算计算值 - 它以以下方式注册依赖项 - 如果在计算期间读取任何可观察值(意味着像 myObservable1() 这样的代码) - 计算值会收到此可观察值的回调,检查其 id 并将其存储在新的依赖项数组中。一旦评估完成 - 旧的依赖数组就被处理。在我们的示例中,当 myObservable1 设置为 false 时,myObservable2 永远不会被读取 - 因为我们从未进入 if block 。所以它不是一个新的依赖项,旧的依赖项已被处理。

2)另一个有趣的事实。考虑片段:

(function () {
var myObservable = ko.observable(0);
var myModel = {
myComputed: ko.computed(function () {
console.log(myObservable());
})
};
myModel = undefined;
myObservable(42); // Outputs 42
})();

计算值不会被垃圾收集器收集,因为事实上对它的引用存在于它的依赖项中。

源代码一览 - ko.compulated (knockout-3.1.0.debug):

function addSubscriptionToDependency(subscribable, id) {
if (!_subscriptionsToDependencies[id]) {
_subscriptionsToDependencies[id] = subscribable.subscribe(evaluatePossiblyAsync);
++_dependenciesCount;
}
}
...
function evaluatePossiblyAsync() {
var throttleEvaluationTimeout = dependentObservable['throttleEvaluation'];
if (throttleEvaluationTimeout && throttleEvaluationTimeout >= 0) {
clearTimeout(evaluationTimeoutInstance);
evaluationTimeoutInstance = setTimeout(evaluateImmediate, throttleEvaluationTimeout);
} else if (dependentObservable._evalRateLimited) {
dependentObservable._evalRateLimited();
} else {
evaluateImmediate();
}
}

保留了对 dependentObservable 的引用,因为保留了对valuatePossulousAsync 的引用(闭包、JS 和所有 Jazz)。

哇,这就是我要说的。希望能想到一些想法。

关于knockout.js - knockout 订阅洞察 : detecting if disposed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30843718/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com