Knockout 组件资源清理和内存管理

资源清理和内存管理

       可选择地,你的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.
  • 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.
  • 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.
  • Manually-created event handlers on external DOM elements, if created inside acreateViewModel 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:

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'
});

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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值