纯计算监控,在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. Hbase压力测试

    PerformanceEvaluation是HBase自带的性能测试工具,该工具提供了顺序读写.随机读写.扫描等性能测试功能.本文简要介绍HBase PerformanceEvaluation的使用方 ...

  2. DrawerLayout,ToolBar 和 TabHost 的使用

    ActionBar 定义起来不方便 toolbar: 最重要的特性,显示menu菜单,右上角三个点的菜单按钮,使用灵活 使用:1,布局文件,包裹LinearLayout 放imageView, 或者I ...

  3. CUDA编程入门,Dim3变量

    dim3是NVIDIA的CUDA编程中一种自定义的整型向量类型,基于用于指定维度的uint3. 例如:dim3 grid(num1,num2,num3): dim3类型最终设置的是一个三维向量,三维参 ...

  4. mvc前端样式自定义

    1.别忘记加 htmlAttributes @Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @clas ...

  5. Windows Server 2008 如何在IIS中添加MIME类型

    用户可以通过使用MIME以设置服务器传送多媒体文件,如声音和视频等.MIME是一种技术规范,现在可以用于浏览器上,传送可以供浏览器识别的信息 如果我们的网站提供下载服务,有时传上去的文件比如 xxx. ...

  6. 去除右键的opendgl

    Windows Registry Editor Version 5.00[-HKEY_CLASSES_ROOT\Unknown\shell\opendlg][-HKEY_CLASSES_ROOT\Un ...

  7. Debian系Linux的dpkg命令

    dpkg "是"Debian Packager "的简写.为 "Debian" 专门开发的套件管理系统,方便软件的安装.更新及移除.所有源自" ...

  8. 虚拟机Q&A

    Q1:虚拟机运行一段时间后,各个版本的第一台虚拟机容量变大,增大容量可以接受 原因:不详 解决方法:用备份镜像替换当前镜像 1.1G Jun 24 17:07 win7_sp1_32_0.qcow2 ...

  9. 基于jdk调用天气服务案例及问题

    问题1:解析wsdl文件时出现 把网络上的wsdl保存到本地,把圈起来的那段删掉 代码: 当返回结果不是String类型时: 输入城市编码去查找 所以: 问题二:如果把本地wsdl文件删除的话需要 三 ...

  10. Unity3D研究院之在把代码混淆过的游戏返混淆回来(七十七)

    最近一直在找如何在MAC上混淆Android的DLL,至今没能找到合适的,有大神知道记得告诉我喔.今天群里有人说了一个混淆代码和返混淆代码的工具de4dot ,不查不知道一查吓一跳.这玩意可以把别人混 ...