纯计算监控(Pure computed observables)
纯计算监控,在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)的更多相关文章
- KnockoutJS 3.X API 第三章 计算监控属性(4)Pure computed observables
Pure computed observables Pure computed observables是KO在3.2.0版本中推出的.她相对于之前的ComputedObservables有很多改进: ...
- 使用计算监控(Using computed observables)
计算监控(Computed Observables) 如果有两个监控属性firstName, lastName,此时我们要显示full name,我们要怎么办呢? 这时,可以创建一个computed ...
- KnockoutJS 3.X API 第三章 计算监控属性(1) 使用计算监控属性
计算监控属性(Computed Observables) 如果你有一个监控属性firstName,和另一个lastName,你要显示的全名?可以使用计算监控属性来实现-它依赖于一个或多个其他监控属性, ...
- Knockout v3.4.0 中文版教程-8-计算监控-纯计算属性
4.纯计算属性 纯计算监控在KO 3.2.0中开始引入,比大多数应用程序使计算监控有更大的性能提升和内存优化.这是因为在自身没有订阅的时候不会保持订阅状态.特性如下 阻止内存泄露 - 避免在应用程序里 ...
- KnockoutJS 3.X API 第三章 计算监控属性(5) 参考手册
计算监控属性构造参考 计算监控属性可使用以下形式进行构造: ko.computed( evaluator [, targetObject, options] ) - 这种形式是创建一个计算监控属性最常 ...
- Knockout v3.4.0 中文版教程-5-计算监控-使用计算监控
3. 计算监控 1.使用计算监控 如果你有一个监控的属性firstName和另一个lastName,但你想显示全名怎么办? 这就是引入计算监控的原因-这是依赖于一个或多个其他的observables函 ...
- Knockoutjs官网翻译系列(三) 使用Computed Observables
书接上回,前面谈到了在视图模型中可以定义普通的observable属性以及observableArray属性实现与UI元素的双向绑定,这一节我们继续探讨第三种可实现绑定的属性类型:computed o ...
- 可写的计算监控(Writable computed observables)
新手可忽略此小节,可写依赖监控属性真的是太advanced了,而且大部分情况下都用不到. 一般情况下,计算监控的值是通过其他监控属性的值计算出来的,因此它是只读的.这个看似很奇怪,我们有什么办法可以让 ...
- Knockout 新版应用开发教程之Computed Observables
Computed Observables 如果你有监控属性firstName和lastName的话,此时如果你想要显示全名? 这个时候computed(以前叫做依赖)监控属性就出马了,这是一个函数用来 ...
随机推荐
- 第一百二十五节,JavaScript,XML
JavaScript,XML 学习要点: 1.IE中的XML 2.DOM2中的XML 3.跨浏览器处理XML 随着互联网的发展,Web应用程序的丰富,开发人员越来越希望能够使用客户端来操作XML技术. ...
- CF Round #355 Div.2
http://codeforces.com/contest/677 B. Vanya and Food Processor 题意:有一个食物加工器,每次能加工不超过h高度的土豆,且每秒加工至多k高度的 ...
- CSS3 Filter滤镜效果
关注到它是在一次分享会当中,很神奇,只需写一行代码就可以变身很美的视觉效果,这就是CSS3滤镜. 语法 filter:fuction(param); 如今浏览器支持情况相比以前乐观很多,点击查看兼容 ...
- Java版冒泡排序和选择排序
一.理解说明 1.理解和记忆 冒泡排序:依次定位数组元素,每次只和相邻的且符合条件的元素交换位置. 选择排序:依次在数组的每个位置,通过逐个对比选择出最大或最小的元素. 2.知识点说明 (1)数组是引 ...
- Hiver 操作 MySQL 导致锁表
Hadoop 搬迁到新集群后,操作主库 MySQL 导致了锁表...sad 具体锁表时间点 : 2016-1-14 14:31 到 2016-1-14 14:36 之间 在 oradba 的 ...
- servlet之过滤器(转载)
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.Filter 1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ...
- 对dpkg: error processing package xxx (--configure) 的处理
这个问题是在在安装Deepdive时候碰到的,具体来说在执行 sudo apt-get update碰到的sudo mv /var/lib/dpkg/info/ /var/lib/dpkg/info_ ...
- Busy Beavers(暴力模拟)
由于排版问题,题目无法显示,可以到 http://7xjob4.com1.z0.glb.clouddn.com/e4872a15819b6bf9d1e5250bacc2a30b 查看 题目大意是有只 ...
- openstack私有云布署实践【2 安装前的服务器基本环境准备】
服务器物理机都安装centos7.2 1511版本 , 此次采用的分区方式全是自动XFS格式LVM,在装系统时就将所有本地raid5硬盘都加入LVM全用了.默认/home目录有着最大的硬盘空间 并且我 ...
- ACdream 1015 Double Kings
假设第一个人选的点为P,并且当作根,那么第二个人选的最优情况必然是根p连着的那些点中的一个.然后枚举一下P即可. #pragma comment(linker, "/STACK:102400 ...