资源清理和内存管理
可选择地,你的viewmodel类可以有一个dispose函数,假如实现,Knockout将调用这个函数,无论什么时候该组件被销毁(例如,因为响应的项被从foreach中除去,或者if绑定变成false)
你必须使用dispose 来除去任何不是被内在的垃圾可收集的资源。例如:
- setInterval回调将继续触发直到被清楚地清除
- 使用clearInterval(handle)去停止它们,否则你的视图模型可能会驻留内存
- ko.computed属性继续从它们的依赖对象接收通知直到北清楚地销毁
- 假如一个依赖是关于一个外部对象,那么确信使用computed的属性.dispose(),否则它(也可能是你的视图模型)将驻留内存,可选地,考虑使用pure computed来避免手工清理的需要
- 订阅observable继续触发直到被清楚地销毁
- 假如你订阅了一个外部observable,确信使用subscription的.dispose(),否则该回调(也可能是你的视图模型)将驻留内存)
- 在外部DOM元素手工创建事件句柄,假如在一个createViewModel函数内创建(或甚至在一个正常的组件视图模型内,虽然MVVM模式不适合你?)必须被除去
- 当然,你不必担心释放在你的视图中使用标准Knockout绑定创建的事件句柄,因为当元素被除去时KO自动的反注册他们)
例如:
var someExternalObservable = ko.observable(123); function SomeComponentViewModel() { this.myComputed = ko.computed(function() { return someExternalObservable() + 1; }, this); this.myPureComputed = ko.pureComputed(function() { return someExternalObservable() + 2; }, this); this.mySubscription = someExternalObservable.subscribe(function(val) { console.log('The external observable changed to ' + val); }, this); this.myIntervalHandle = window.setInterval(function() { console.log('Another second passed, and the component is still alive.'); }, 1000); } SomeComponentViewModel.prototype.dispose = function() { this.myComputed.dispose(); this.mySubscription.dispose(); window.clearInterval(this.myIntervalHandle); // this.myPureComputed doesn't need to be manually disposed. } ko.components.register('your-component-name', { viewModel: SomeComponentViewModel, template: 'some template' });
仅仅依赖同一视图模型对象的computed和subscription不是严格需要销毁的,因为这仅仅创建了一个Javascript垃圾收集器知道如何释放的循环参考。然而,为了避免必须记得哪些东西需要清理,只要有可能,你最好使用pureComputed,不管是不是在技术尚必要,都显式地销毁所有其他computeds/subscriptions。
原文:
Disposal and memory management
Optionally, your viewmodel class may have a dispose
function. If implemented, Knockout will call this whenever the component is being torn down and removed from the DOM (e.g., because the corresponding item was removed from aforeach
,
or an if
binding has become false
).
You must use dispose
to release any resources that aren’t inherently garbage-collectable. For example:
setInterval
callbacks will continue to fire until explicitly cleared.- Use
clearInterval(handle)
to stop them, otherwise your viewmodel might be held in memory.
- Use
ko.computed
properties continue to receive notifications from their dependencies until explicitly disposed.- If a dependency is on an external object, then be sure to use
.dispose()
on the computed property, otherwise it (and possibly also your viewmodel) will be held in memory. Alternatively, consider using apure
computed to avoid the need for manual disposal.
- If a dependency is on an external object, then be sure to use
- Subscriptions to observables continue to fire until explicitly disposed.
- If you have subscribed to an external observable, be sure to use
.dispose()
on the subscription, otherwise the callback (and possibly also your viewmodel) will be held in memory.
- If you have subscribed to an external observable, be sure to use
- Manually-created event handlers on external DOM elements, if created inside a
createViewModel
function (or even inside a regular component viewmodel, although to fit the MVVM pattern you shouldn’t) must be removed.- Of course, you don’t have to worry about releasing any event handlers created by standard Knockout bindings in your view, as KO automatically unregisters them when the elements are removed.
For example:
|
It isn’t strictly necessary to dispose computeds and subscriptions that only depend on properties of the same viewmodel object, since this creates only a circular reference which JavaScript garbage collectors know how to release. However, to avoid having
to remember which things need disposal, you may prefer to use pureComputed
wherever possible, and explicitly dispose all other computeds/subscriptions whether technically necessary or not.