命令式编程、声明式编程、响应式编程与 RxJS

命令式编程、声明式编程、响应式编程

命令式编程(Imperative):详细的命令机器怎么(How)去处理一件事情以达到你想要的结果(What);
声明式编程(Declarative):只告诉你想要的结果(What),机器自己摸索过程(How)。

出自:《命令式编程(Imperative) vs 声明式编程(Declarative)》

命令式编程是我们一步一步告诉机器需要怎么做,机器按部就班地执行命令。声明式编程是我们告诉机器我想要这样的结果,而不管他是怎么实现的,这更符合人类的思维。举一个数据过滤的例子来说明这一点,比如我们要打印下数组中存不存在 3。

示例1:

// 命令式编程做法
let res = false;
for(i = 0; i < dataArr.length; i++) {
    if (i === 3) {
        res = true;
    }
}
console.log(res);

// 声明式编程做法
let res = dataArr.filter(i => i === 3);
console.log(res);

Angular 中的 RxJS,用了“声明式编程范式”,是一个使用可观察对象实践“响应式编程”模型的库。那什么是响应式编程呢?

它希望有某种方式能够构建关系,而不是执行某种赋值命令。
响应式编程是一种通过异步和数据流来构建事务关系的编程模型。

出自:《重新理解响应式编程》

构建关系是指我们可以定义两个变量(A 和 B)之间具有某种永恒的关系。一旦 A 变量改变,我们不需要人为地对 B 变量进行任何处理,B 变量自动更改以满足与 A 变量已经定义好的关系。

示例2:

A = 1;

B - A := 2;     // 定义一种关系,这里是指 B 减去 A 永远等于 2
console.log(B); // B = 3

A = 3;          // A 改变
console.log(B); // B = 5

数据流是响应式编程传递变化的值的方式,通过数据流将变化的数据不断向下传递。因此,我们可以链式的对数据处理。

示意图1:
data-flo
上图与命令式编程的不同之处是:命令式编程我们会一步步的去实现花括号里面的操作,不是“我要颜色深一点”,而是“我让颜色深一点”。

可以说响应式编程是声明式编程的一种,两者到底是从属关系还是其他关系,并不十分清楚,这似乎并不重要。个人倾向于把响应式编程当做一种更具体的声明式编程,是声明式编程的更高级范式。

RxJS

RxJS 是 JS 版本的 ReactiveX 库,ReactiveX 还有 JAVA、.NET、Swift 等语言的版本。无意造轮子,此篇仅对 RxJS 做一个标记式的记录和学习指引,详细了解可查阅:《RxJS 官网文档》(英文)以及《RxJS 中文文档》

RxJS 是使用 Observables 的响应式编程的库,它提供了一系列 API 来支持响应式编程。

学习 RxJS 有几个概念和注意点需要重点知晓:

  • Observable(可观察对象):RxJS 处理的数据或者是 RxJS 抽象操作或者数据的方式,它是函数的泛化,支持返回多个值,惰性运算,需要被订阅之后才会执行。使用 RxJS,就是在构造 Observable 和处理 Observable。
  • Subscription (订阅):观察者对象,或者说是订阅 Observable 的那个对象,更进一步可以说是接收 Observable 返回值的那个对象。
  • Subject (主体):可以理解为支持多播的 Observable。Subjects 是将任意 Observable 执行共享给多个观察者的唯一方式。
  • RxJS 的操作符:提供便捷的数据(事件流)处理,比如 map、filter,以及 combineAll、forkJoin、pairwise 等。
  • Rx.Observable.create 是 Observable 构造方法的别名,它通知是下面这个样子:
  Rx.Observable.create({
      next: Function,
      error: Function,
      complete: Function
  });

RxJS 还提供了 from of 等其他创建 Observable 的方法。

  • Observables 并不是异步编程,传递值可以是同步的,也可以是异步的。
  • 在 Observable 执行中, 可能会发送零个到无穷多个 “Next” 通知。如果发送的是 “Error” 或 “Complete” 通知的话,那么之后不会再发送任何通知了。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注