纯计算监控,在knockout 3.2.0里才有,提供了对性能和内存更好的管理。这是因为纯计算监控不包含对他的依赖的订阅。特点有:

  • 防止内存泄漏
  • 降低计算开销:值不再是observed,是一个不会重新计算的computed observables.

根据是否有订阅,pure computed observable会自动在两状态间进行切换:

1. 当没有订阅者(subscribers)时,是sleeping状态。当进入sleeping状态时,会释放所有依赖的订阅。在这个状态期间,它不会订阅任何在函数中使用到的observable属性(但是通过getDependenciesCount()还是得到的数值是包括它的)。如果在sleeping期间,computed observable的值被读取了,它马上就会被重新计算。

2. 当有订阅者(subscriber)时,会变成listening。当进入listening状态,马上应该会调用计算函数。在这种状态下,它就和普通的computed observable是一样的。具体可以参见 how dependency tracking works.

为什么使用 "pure" ?

先来看下网上介绍的“纯函数”的介绍:

纯函数(Pure Function)与外界交换数据只有唯一渠道——参数和返回值。其在逻辑上没有副作用(译注:副作用就是潜在地和函数的外部环境交换数据)——这当然只是从抽象角度来说。从现实角度讲,任何函数在CPU级别上都存在副作用,大多数函数在堆级别上也有副作用。可就算有这些副作用,这种在逻辑层面上的抽象也是有意义的。

纯函数不读写全局变量,无状态、无IO,不改变传入的任何参数。理想情况下,不会给他传入任何外部数据,因为一旦传入一个诸如allMyGlobals的指针,上面的这些规则就都被打破了。

这里借用pure functions因为它们的特殊很像:

1. 执行computed observable不会产生任何的副作用。

2. computed observable的值不依赖于其他隐藏的信息,它的值应该是基于其他的observables的,这些值都可以看作是定义computed observable函数的参数。

语法

标准的语法是使用ko.pureComputed:

this.fullName = ko.pureComputed(function() {
return this.firstName() + " " + this.lastName();
}, this);

另外,也可以使用ko.computed选项:

this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this, { pure: true });

更多的语法说明,请参见 computed observable reference.

何时使用pure computed observable

当程序设计中包括可持久性的view model被其他temporary views和viewmodels使用时,使用pure computed observables在可持久化的view model中,可提高性能(但不总是这样)。在temporary view models中使用会优化内存。(还没感觉到这两点带来的好处)。

下面的例子,是一个简单的wizard的示例,先输入first name,再输入 last name, 最后会显示 full name:

(由于Full Name在一开始不显示,Full name在输入它的依赖项时,并不会调用,只有当full name显示出来时,才会调用。 就不贴图了,挺麻烦的,直接把html和js放到一个html里就可以运行了,或者参见knockout网站http://knockoutjs.com/documentation/computed-pure.html,不过这里给的界面和HTML对不上,但功能是一样的):

<div class="log" data-bind="text: computedLog"></div>
<!--ko if: step() == 0-->
<p>First name: <input data-bind="textInput: firstName" /></p>
<!--/ko-->
<!--ko if: step() == 1-->
<p>Last name: <input data-bind="textInput: lastName" /></p>
<!--/ko-->
<!--ko if: step() == 2-->
<div>Prefix: <select data-bind="value: prefix, options: ['Mr.', 'Ms.','Mrs.','Dr.']"></select></div>
<h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
<!--/ko-->
<p><button type="button" data-bind="click: next">Next</button></p>
function AppData() {
this.firstName = ko.observable('John');
this.lastName = ko.observable('Burns');
this.prefix = ko.observable('Dr.');
this.computedLog = ko.observable('Log: ');
this.fullName = ko.pureComputed(function () {
var value = this.prefix() + " " + this.firstName() + " " + this.lastName();
// Normally, you should avoid writing to observables within a pure computed
// observable (avoiding side effects). But this example is meant to demonstrate
// its internal workings, and writing a log is a good way to do so.
this.computedLog(this.computedLog.peek() + value + '; ');
return value;
}, this); this.step = ko.observable(0);
this.next = function () {
this.step(this.step() === 2 ? 0 : this.step()+1);
};
};
ko.applyBindings(new AppData());

(可以试着把computedLog.peek()改成computedLog(),运行时,会提示不可以循环调用。 但是把pureComputed改成computed,然后再使用computedLog()就不会有这个提示。 不知道为什么。)

何时不使用pure computed observable

副作用

当依赖的属性改变时需要马上执行一定操作时,例如:

在computed observable中要调用callback函数

ko.computed(function () {
var cleanData = ko.toJS(this);
myDataClient.update(cleanData);
}, this);

在绑定的init函数中,使用computed observable更新绑定元素

ko.computed({
read: function () {
element.title = ko.unwrap(valueAccessor());
},
disposeWhenNodeIsRemoved: element
});

使用pure computed的一个明显的副作用是计算函数并不是在订阅者的值改变时就会调用(因为它是sleeping的)。当依赖的值改变时一定要调用计算函数时,这种情况下是不可以使用pure computed的,应该使用regular computed。

性能

使用pure computed observable也可能引起比较大的性能开销,正常的computed observable会在依赖的值改变时才会触发,但是pure computed observable每一次访问都会计算一次。这在某些情况下可能导至性能开销过大。

纯计算监控(Pure computed observables)的更多相关文章

  1. KnockoutJS 3.X API 第三章 计算监控属性(4)Pure computed observables

    Pure computed observables Pure computed observables是KO在3.2.0版本中推出的.她相对于之前的ComputedObservables有很多改进: ...

  2. 使用计算监控(Using computed observables)

    计算监控(Computed Observables) 如果有两个监控属性firstName, lastName,此时我们要显示full name,我们要怎么办呢? 这时,可以创建一个computed ...

  3. KnockoutJS 3.X API 第三章 计算监控属性(1) 使用计算监控属性

    计算监控属性(Computed Observables) 如果你有一个监控属性firstName,和另一个lastName,你要显示的全名?可以使用计算监控属性来实现-它依赖于一个或多个其他监控属性, ...

  4. Knockout v3.4.0 中文版教程-8-计算监控-纯计算属性

    4.纯计算属性 纯计算监控在KO 3.2.0中开始引入,比大多数应用程序使计算监控有更大的性能提升和内存优化.这是因为在自身没有订阅的时候不会保持订阅状态.特性如下 阻止内存泄露 - 避免在应用程序里 ...

  5. KnockoutJS 3.X API 第三章 计算监控属性(5) 参考手册

    计算监控属性构造参考 计算监控属性可使用以下形式进行构造: ko.computed( evaluator [, targetObject, options] ) - 这种形式是创建一个计算监控属性最常 ...

  6. Knockout v3.4.0 中文版教程-5-计算监控-使用计算监控

    3. 计算监控 1.使用计算监控 如果你有一个监控的属性firstName和另一个lastName,但你想显示全名怎么办? 这就是引入计算监控的原因-这是依赖于一个或多个其他的observables函 ...

  7. Knockoutjs官网翻译系列(三) 使用Computed Observables

    书接上回,前面谈到了在视图模型中可以定义普通的observable属性以及observableArray属性实现与UI元素的双向绑定,这一节我们继续探讨第三种可实现绑定的属性类型:computed o ...

  8. 可写的计算监控(Writable computed observables)

    新手可忽略此小节,可写依赖监控属性真的是太advanced了,而且大部分情况下都用不到. 一般情况下,计算监控的值是通过其他监控属性的值计算出来的,因此它是只读的.这个看似很奇怪,我们有什么办法可以让 ...

  9. Knockout 新版应用开发教程之Computed Observables

    Computed Observables 如果你有监控属性firstName和lastName的话,此时如果你想要显示全名? 这个时候computed(以前叫做依赖)监控属性就出马了,这是一个函数用来 ...

随机推荐

  1. 【Python】Python中对象管理与垃圾回收中两个很有意思的问题

    再Python中是利用引用计数来实现对象管理和垃圾回收的,即其他对象引用该对象时候,其引用计数加1,反之减1,当引用计数为0时候,被垃圾收集器回收. Python解释器对对象以及计数器的管理分为以下两 ...

  2. child_process小解

    js是一种单进程单线程的语言,但现行的cpu都是多核的,为了解决单进程单线程对多核使用不足的问题,child_process应运而生,理想情况下每个进程各自利用一个内核. 主要有四种方法来创建子进程, ...

  3. namenode无法启动

    查看日志错误信息关键语句: There appears to be a gap in the edit log.  We expected txid 44353, but got txid 原因: n ...

  4. Hadoop datanode 磁盘自动化处理

    新集群的 datanode 磁盘自动化处理工具开工在即.

  5. EasyUI 日期选择插件封装成选择到月份的插件

    将普通的日期选择插件封装成选择到月份的插件:                     var nowMonth = new Date();                    var month = ...

  6. Busy Beavers(暴力模拟)

    由于排版问题,题目无法显示,可以到 http://7xjob4.com1.z0.glb.clouddn.com/e4872a15819b6bf9d1e5250bacc2a30b  查看 题目大意是有只 ...

  7. NPM使用介绍

    NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署的很多问题,常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用 允许用户NPM服务器下载并安装别 ...

  8. redis 5 种数据结构

    常用命令 就DB来说,Redis成绩已经很惊人了,且不说memcachedb和tokyocabinet之流,就说原版的memcached,速度似乎也只能达到这个级别.Redis根本是使用内存存储,持久 ...

  9. 腾讯应用开发3006 : name lookup timed out 错误

    昨天到今天发现应用访问不正常,用户发表数据很少,一查日志,QQ的 openApi 返回的结果全是 name lookup timed out,莫名其妙. 在服务器上 ping , nslookup , ...

  10. 新项目引入gulp

    1:安装npm:官网下载nodejs--https://nodejs.org/en/.进行安装npm;--http://jingyan.baidu.com/article/a17d528506d7f5 ...