纯计算监控(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(以前叫做依赖)监控属性就出马了,这是一个函数用来 ...
随机推荐
- 无线hacking系统—wifislax
简介 官方中文网站: http://wifislax.cn/ WiFiSlax 是在Slax基础上定制出来的,由西班牙开发.它包含了各种各样的安全和诊断工具.该发行主要的成名原因是把各种各样的非官方网 ...
- CentOS 6.5静态IP的设置(NAT和桥接都适用)
CentOS 6.5静态IP的设置(NAT和桥接都适用) 为了方便,用Xshell来.并将IP设置为静态的.因为,在CentOS里,若不对其IP进行静态设置的话,则每次开机,其IP都是动态变化的,这样 ...
- 图片翻转(Raw Image)
int TransformImageBuffer(unsigned char* pImageBuffer, int width, int height,unsigned char* targetIma ...
- delphi变量作用域
完全摘自网络(一件飘雪),供参考: 很多初学者对delphi单元的变量和函数访问权限不理解,在此我举例说明,希望初学者看此文后能茅塞顿开. delphi单元的变量和函数访问权限问题如下两个单元描述: ...
- 微信小程序 textarea 简易解决方案
微信小程序中textarea没有bindchange事件,所以无法在输入时给变量赋值. 虽然可以使用bindblur事件,但是绑定bindblur事件,如果再点击按钮,则先执行完按钮事件后,再去执行b ...
- Leetcode - 186 Reverse Words in a String II
题目: Given an input string, reverse the string word by word. A word is defined as a sequence of non-s ...
- centos7内核升级
默认centos7的内核版本是3.10,升级的原因是为了测试openvswitch的vlan技术,默认openvswitch的2.3版本是允许centos7默认内核3.10支持,下面是软件与内核版本对 ...
- java中转换json方式(JSONArray,JSONObject),json解析
package com.yunos.tv.video.resource.controller.web; import java.util.ArrayList; import java.util.Has ...
- WEB服务器:Apache、Tomcat、JBoss、WebLogic、Websphere、IIS的区别与关系
1)Apache 免费,世界使用排名第一的Web服务器.它可以运行在几乎所有广泛使用的计算机平台上.Apache的特点是简单.速度快.性能稳定,并可做代理服务器来使用.Apache是以进程为基础的结 ...
- 【cocos2d-js 3.0】制作2048
2048:在一个4X4的方阵中,玩家需要滑动上面的数字,如果俩个数字相邻并且相等,则相加,需要达到2048,方可胜利. 因为在浏览器操作,所以此例的操作方法为:键盘上的w,s,a,d代表上下左右,也可 ...