Knockoutjs 响应式计算研究
reactive programming
https://en.wikipedia.org/wiki/Reactive_programming
In computing, reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. With this paradigm it is possible to express static (e.g., arrays) or dynamic (e.g., event emitters) data streams with ease, and also communicate that an inferred dependency within the associated execution model exists, which facilitates the automatic propagation of the changed data flow.[citation needed]
a := b + c {\displaystyle a:=b+c}
would mean that a {\displaystyle a}
is being assigned the result of b + c {\displaystyle b+c}
in the instant the expression is evaluated, and later, the values of b {\displaystyle b}
and c {\displaystyle c}
can be changed with no effect on the value of a {\displaystyle a}
. On the other hand, in reactive programming, the value of a {\displaystyle a}
is automatically updated whenever the values of b {\displaystyle b}
or c {\displaystyle c}
change, without the program having to re-execute the statement a := b + c {\displaystyle a:=b+c}
to determine the presently assigned value of a . {\displaystyle a.}
[citation needed]
Reactive programming has been proposed as a way to simplify the creation of interactive user interfaces and near-real-time system animation.[citation needed]
For example, in a model–view–controller (MVC) architecture, reactive programming can facilitate changes in an underlying model that are reflected automatically in an associated view.[1]
knockoutjs reactive
https://knockoutjs.com/documentation/observables.html
第一,定义 基础的 可观察对象:
var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable(123)
};
第二, 定义存在依赖其他可观察对象的 计算对象
function AppViewModel() {
// ... leave firstName and lastName unchanged ...
this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
}
第三、绑定到视图
The name is <span data-bind="text: fullName"></span>
如果基础的 可观察对象 改变, 则视图会自动跟着改变。
实现原理
https://github.com/fanqingsong/knockout-prototype
knockout模块实现, 包括 observale 和 computed 接口实现, 以及内部依赖管理实现。
let ko = {}
ko.say = () => console.log("hello world")
ko.dependency = (() => {
let callerstack = []
let currentCaller
return {
currentCaller,
callerstack
}
})();
ko.observable = (initVal) => {
// for record caller, ie observer
let observerCache = [];
// store current observable value
let currentVal = "";
if(initVal !== undefined){
console.log("initVal 0=", initVal)
currentVal = initVal;
}
let observable = (newVal) => {
// for read, subscribe to caller
if( newVal === undefined ) {
if (ko.dependency.currentCaller) {
observerCache.push(ko.dependency.currentCaller)
}
return currentVal;
// for write
} else {
currentVal = newVal;
console.log("===",observerCache.length)
for (const index in observerCache) {
console.log("-----------3-", observerCache[index]);
observerCache[index].callEvalWithDeps();
}
}
}
return observable
}
ko.computed = (evalFunc) => {
// store current observable value
let currentVal = "";
let unValuated = true;
let computedObservable = () => {
if (unValuated){
computedObservable.callEvalWithDeps();
unValuated = false;
}
return currentVal;
}
computedObservable.callEvalWithDeps = () => {
if (ko.dependency.currentCaller) {
ko.dependency.callerstack.push(ko.dependency.currentCaller)
}
ko.dependency.currentCaller = computedObservable;
currentVal = evalFunc();
let parent = ko.dependency.callerstack.pop();
ko.dependency.currentCaller = parent;
}
return computedObservable
}
module.exports = ko
调用
import ko from "./knockout.js"
ko.say(); let aObservable = ko.observable("a");
console.log("aObservable=", aObservable()); let bComputed = ko.computed(() => {
let result = aObservable() + "b"; console.log("result=", result); return result;
}) // bind subscription to aObservable
let bVal = bComputed();
console.log("bVal=", bVal); // trigger reactive effect
aObservable("c"); console.log("bComputed=", bComputed())
运行

参考:
https://knockoutjs.com/documentation/computed-dependency-tracking.html
https://www.reactivemanifesto.org/
Knockoutjs 响应式计算研究的更多相关文章
- 理解rem实现响应式布局原理及js动态计算rem
前言 移动端布局中,童鞋们会使用到rem作为css单位进行不同手机屏幕大小上的适配.那么来讲讲rem在其中起的作用和如何动态设置rem的值. 1.什么是rem rem是相对于根元素(html标签)的字 ...
- Vue 2.0 v-for 响应式key, index及item.id参数对v-bind:key值造成差异研究
Vue 2.0 v-for 响应式key, index及item.id参数对v-bind:key值造成差异研究 在github上阅览README.md以获得最佳阅读体验,点这里 v-for响应式key ...
- 响应式疑惑? CSS单位研究
各种单位要搞清楚,自己试一试,实践出真知! 2.屏幕分辨率 响应式 哦,电脑的分辨率:1440x900表示水平有1440个像素点哦! 垂直有900个像素点. 而网页在浏览器中,所以宽度是电脑的分 ...
- Bootstrap响应式栅格系统的设计原理
1.历史背景 Bootstrap是Twitter的工程师Mark Otto和Jacob Thornton开发的一套供内部使用的UI框架,于2011年开源.2012年发布的第二版中新增了12列栅格系统和 ...
- html5 getComputedStyle + resize 实现动态宽高度等比响应式页面设计
序:通常我们只能控制div的宽度 而不能控制高度,在响应式页面里 如果要这个div是正方形那么必须的用媒体查询在不同的分辨率下写死宽高度 今天突发奇想研究了个 用百分比来动态控制div的高度让其与宽度 ...
- JGUI源码:响应式布局简单实现(13)
首先自我检讨下,一直没有认真研究过响应式布局,有个大致概念响应式就是屏幕缩小了就自动换行或者隐藏显示,就先按自己的理解来闭门造车思考实现过程吧. 1.首先把显示区域分成12等分,bootstrap是这 ...
- (转)Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门
http://www.ityouknow.com/springboot/2019/02/12/spring-boot-webflux.html Spring 5.0 中发布了重量级组件 Webflux ...
- Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门
Spring 5.0 中发布了重量级组件 Webflux,拉起了响应式编程的规模使用序幕. WebFlux 使用的场景是异步非阻塞的,使用 Webflux 作为系统解决方案,在大多数场景下可以提高系统 ...
- 函数响应式编程(FRP)从入门到”放弃”——基础概念篇
前言 研究ReactiveCocoa一段时间了,是时候总结一下学到的一些知识了. 一.函数响应式编程 说道函数响应式编程,就不得不提到函数式编程,它们俩到底有什么关系呢?今天我们就详细的解析一下他们的 ...
随机推荐
- 海思uboot启动流程详细分析(一)
第一阶段 start.S 首先我们可以在u-boot.lds中看到ENTRY(_start),即指定了入口_start,_start也就是整个start.S的最开始: 1. reset 在arch\a ...
- PIC单片机基础1
1.PIC单片机总线结构——哈佛结构:即指令和数据空间是完全分开的,所以与常见的微控制器不同的一点是,程序和数据总线可以采用不同的宽度.以PIC16F684单片机为例,数据总线是8位的,但指令总线位数 ...
- python中os模块和sys模块的常见用法
OS模块的常见用法 os.remove() 删除文件 os.rename() 重命名文件 os.walk() 生成目录树下的所有文件名 os.chdir() 改变目录 os.mkd ...
- HTML基础-------HTML标签(3)
HTML标签(3) 表格 作用:制作一个表格 属性: 标签;table>tr>td(或者th) 语义; table:一个表格 tr:一行 td:一个单元格 th:单元格的表头 captio ...
- git 多用户多仓库配置
ssh全称是Secure Shell,即安全Shell,是一种可以进行安全远程登录的协议,在Linux中以OpenSSH为代表,Windows中则有Putty作为实现.ssh的会话建立阶段类似TCP协 ...
- Cleartext HTTP traffic to xxx not permitted解决办法
,为保证用户数据和设备的安全,针对下一代 Android 系统(Android P) 的应用程序,将要求默认使用加密连接,这意味着 Android P 将禁止 App 使用所有未加密的连接,因此运行 ...
- [kuangbin带你飞]专题二十二 区间DP-E-POJ - 1651
区间DP模板题 做区间DP的题目的时候,我们考虑DP[i][j]的含义是什么? 由题意大概是这样的,我们可以从n个数中每次选一个我们以前没选过的数字拿走,需要消耗a[i]*a[i+1]*a[i-1]的 ...
- 文件实时同步(rsync+inotify)
目标服务器:10.11.6.11 源服务器:10.11.6.12 准备条件: 1.关闭selinux: vi /etc/selinux/config #编辑防火墙配置文件 #SELINUX=enfor ...
- php框架之phalcon
1.开发助手 1) 下载 git clone https://github.com/phalcon/cphalcon.git git clone https://github.com/phalcon/ ...
- Linux下Nginx配置阿里云 SSL证书实现HTTPS访问
这篇文章主要介绍了nginx配置ssl证书实现https访问的示例 1.服务器系统:Centos 2. 阿里云申请SSL证书 选择“免费版DV SSL”,点击立即购买: 下载证书 列表中找到已签发的证 ...