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/

最新文章

  1. MVVM下listbox默认显示最后一行
  2. 配置LVS + Keepalived高可用负载均衡集群之图文教程
  3. SpringMVC常用注解實例詳解1:@Controller,@RequestMapping,@RequestParam,@PathVariable
  4. java面向对象编程— —第七章 继承
  5. 当ASP.NET MVC模型验证遇上CKEditor
  6. 第二篇、HTML5新增标签
  7. [React Native] Error Handling and ActivityIndicatorIOS
  8. JQ 让光标在文本框最末尾
  9. ubuntu14.04 制作U盘启动文件
  10. Entity Framework Core 2.0 中使用LIKE 操作符
  11. CKEditor与dotnetcore实现图片上传
  12. 济南清北学堂游记 Day 0.
  13. 7. VIM 系列 - 程序员利器(语法检测、代码块补全、symbol管理、函数跳转)
  14. Java的get、post请求
  15. ECMA Script 6_ 类 class
  16. 机器学习入门03 - 降低损失 (Reducing Loss)
  17. go关键字之type用法
  18. java之导入excel
  19. 【转】IE内嵌google chrome frame解决浏览器兼容问题
  20. C语言realloc,malloc,calloc的区别【转载】

热门文章

  1. 【Spring Cloud笔记】 Eureka通过集群实现高可用
  2. Web前端教程4-JQuery教程
  3. [认证授权] 2.OAuth2授权(续) &amp; JWT(JSON Web Token)
  4. 借助FreeHttp任意篡改http报文 (使用&#183;实现)
  5. 01-Redhat/Centos7网卡命名介绍及修改方式
  6. python操作随笔
  7. delphi7 编译的程序在win7下请求获得管理员权限的方法
  8. Linux学习之路1
  9. java UTC时间格式化
  10. BZOJ5019[Snoi2017]遗失的答案——FWT+状压DP