ko.pureComputed - 清除缓存中的缓存值

时间:2017-04-18 14:56:28

标签: javascript knockout.js

我有一些ko.pureComputed属性,通常会在自身内部存储大量数据。 当这些ko.pureComputed属性进入 sleep 状态(没有人订阅它们)时,我不再需要这些数据,直到他们回到 listen 状态(有人订阅了他们)。

在这段时间内,当他们处于 sleep 状态时,我希望ko.pureComputed属性清除它们的值,以便垃圾收集器可以从内存中删除该计算数据,然后,当我再次需要计算数据时,也就是说,当ko.pureComputed返回到监听状态时,我想重新计算计算数据。

这可能吗?

有关我的用例场景的更多详细信息:

我的网站是单页应用程序,意味着Javascript框架( Durandal )为用户显示切换页面(HTML和JS)。

某些页面需要存储大量数据的计算属性。我希望将ko.pureComputed用于此目的,因为一旦用户离开其页面,即一旦ko.pureComputed进入 sleep 状态,它就会停止更新因为它没有更多的听众。

Durandal 在用户离开或访问页面时,将页面的JS视图模型从HTML视图中重新分配并重新附加到HTML视图中

问题是ko.pureComputed保持其最新值被缓存。 在我的例子中,这些值是大型对象的大型数组,占用了大量的内存。我不想再处理这些数据了。

有没有办法在{{1>}进入 sleep 状态(当用户离开页面时)时清除缓存的值,然后在ko.pureComputed时重新初始化{ {1}}返回监听状态(当用户重新访问该页面时)?

2 个答案:

答案 0 :(得分:2)

使用纯计算的状态更改事件,我们可以告诉计算机在其休眠时清除其值。这是一个包装函数,可以全部设置:

function computedValueOnlyWhenActive(readFunction) {
    var isAwake = ko.observable(false),
        theComputed = ko.pureComputed(function () {
            if (isAwake()) {
                return readFunction();
            }       
        });

    theComputed.subscribe(function() {
        isAwake(true);
    }, undefined, "awake");
    theComputed.subscribe(function() {
        isAwake(false);
        theComputed.peek(); // force reevaluation
    }, undefined, "asleep");

    return theComputed;
}

演示:https://jsfiddle.net/mbest/gttosLzc/

答案 1 :(得分:1)

这不是您提出的具体问题的答案,但根据您的具体情况,这可能是一个更有帮助的答案。

在Durandal中,路由器插件通过使用requireJS调用异步加载指定的模块进行导航。一旦它检索到模块,它就会检查结果是对象还是函数,如果它是一个函数,它将从函数中实例化一个新对象。如果它是一个对象,它只使用该对象。

RequireJS会自动缓存它检索到的模块,因为如果模块已经下载了模块,它就不会从服务器重新获取模块。因此,如果您的模块定义是普通对象,那么每次都会显示相同的对象。

此模块定义将在导航之间保存其状态:

define(['durandal/app'], function (app) {
    var title = 'myView';
    var vm = {
        title: title;
    };

    return vm;
});

此模块定义将创建一个新对象,并将重新绑定所有敲除绑定,从而在每个导航中生成一个新加载的屏幕。

define(['durandal/app'], function (app) {
    var title = 'myView';
    var vm = function(){
        this.title = title;
    };

    return vm;
});

修改 对于更细粒度的durandal解决方案,也适用于较旧版本的淘汰赛(即在pureComputed之前),您可以将这个概念与迈克尔最佳结合使用isAwake observable和durandal的视图激活和停用生命周期钩子。

function viewModel(){
    var self = this;
    this.isAwake = ko.observable(true);

    this.theComputed = ko.computed(function () {
        if (isAwake()) {
            return myValue();
        }       
        return "";
    });

    this.activate = function(){
        self.isAwake(true);
    }
    this.deactivate = function(){
        self.isAwake(false);
    }
}
var vm = new viewModel();
return vm; //return the instance not the function

http://durandaljs.com/documentation/Hooking-Lifecycle-Callbacks.html