纯计算监控(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(以前叫做依赖)监控属性就出马了,这是一个函数用来 ...
随机推荐
- sql数据导出导入格式化
SHELL脚本导入导出数据时,按逗号分隔,引号包含字段,null值'' gccli -uroot -h$ip -e"rmt:${sqlStr} into outfile '${name}${ ...
- 第一百一十六节,JavaScript,DOM操作样式
JavaScript,DOM操作样式 一.操作样式 CSS作为(X)HTML的辅助,可以增强页面的显示效果.但不是每个浏览器都能支持最新的CSS能力.CSS的能力和DOM级别密切相关,所以我们有必要检 ...
- Scala 中的 apply 和 update 方法[转]
原文链接:http://blog.csdn.net/lyrebing/article/details/21696581 Scala 是构建在 JVM 上的静态类型的脚本语言,而脚本语言总是会有些约定来 ...
- win8,win10安装mysql
以管理员身份进到命令窗口后,找到要安装的文件,执行msiexec /package mysql-installer-community-5.7.16.0.msi 回车即可
- echarts x轴或y轴文本字体颜色改变
1:x轴文本字体颜色改变 xAxis : [ { type : 'category', data : ['<30','30-','40-','50-','60-','>=70'], axi ...
- 【Python之路】第三篇--Python基本数据类型
运算符 1.算数运算: # 在py2的 取整除运算中 9//2 = 4.0 # 引入 from __future__ import division 9//2 = 4.5 # py3中不需要! 2.比 ...
- JavaScript里利用DOM获取宽高大全
网页可见区域宽:document.body.clientWidth网页可见区域高:document.body.clientHeight网页可见区域宽:document.body.offsetWidth ...
- PHP中 post 与get的区别 详细说明
1.Get 方法通过 URL 请求来传递用户的数据,将表单内各字段名称与其内容,以成对的字符串连接,置于 action 属性所指程序的 url 后,如[url]http://www.jincaib.c ...
- Redis的windows安装
第一步:下载Windows下的Redis链接:http://web.kuaipan.cn/n/drive/files/179275650081763322 第二不:打开cmd窗口命令:定位的Redis ...
- javaWEB总结(16):jsp错误页面的处理
前言 网站上线后,jsp页面上有时会出现不友好的错误信息,我们需要展示给用户更加友好的页面.这时候要用到page标签的errorPage和isErrorPage. errorPage 指定当前页面出现 ...