数据的生产者/消费者与推拉模式(Push/Pull)

将数据看作是商品, 生产数据的是生产者, 使用数据的是消费者.

生产者有很多, Function / Promise / Generator / Iterator / RxJS. 等等.

但这些生产者的类型却不一样, 它们被分为 Push(推模式) 和 Pull(拉模式).

拉模式的生产者更加常见, 比如: Function, Iterator 等.

如何区分推和拉.

对于拉模式来说, 何时生成数据是由消费者决定的, 比如 function, 是在用的时候产生数据. 你不用, 它就不产生.
对于推模式来说, 何时生成数据是由生产者决定的, 比如 Promise, 我自己把数据拿到, 然后将状态固定(resolved), 你什么时候要用, 就 .then 获取即可.

也就是说. 推模式更加适合"异步请求"或"事件". 因为这两种情况下, 数据的产生并不受消费者调用而直接获取的. 它们的产生是由请求成功 / 事件触发这些情况决定的.

从表现来看, 推模式在代码中常常表现为"链式调用", 比如: Fetch(url).then(), 而拉模式则是同步立即获取, 比如: Date.now()

惰性执行与主动执行

所谓惰性执行, 指的是某段代码, 自他声明以后, 需要调用才会执行. 主动执行则相反, 会在声明后立刻执行.
前者的典型代表是 Function, 此外 Generator 和 Iterator 也是, RxJS 也是, 但它不是调用后执行, 而是订阅后执行.
后者(主动执行)的典型代表是 Promise, 它会将执行的结果保存好, 状态固定, 后续无论调用多少次都是一样的值, 因为它已经计算完了. 不受外界影响.

let count = 1

function getCount() {
  return new Promise(resolve => {
    count++
    resolve(count)
  })
}

const promise = getCount()
promise.then(console.log) // 2
promise.then(console.log) // 2
promise.then(console.log) // 2
promise.then(console.log) // 2

订阅一个 Observable 就像调用一个函数

由于 RxJS 也是惰性执行的, 它跟函数是非常类似的. 也因此, RxJS 是一种纯函数编程的库. 下面例子中函数调用使用 .call, Observable 调用使用 .subscribe, 两者其实是类似的. 只是 函数调用是 拉模式, Observable 是推模式.

// 1. 函数调用
function foo() {
  console.log('Hello, World!')
  return 42
}

console.log(foo.call())
// Hello, World!
// 42

// ----------------------------------------

// 2. RxJS Observable
import { Observable } from 'rxjs'

const observable = new Observable(subscriber => {
  console.log('Hello, World!')
  subscriber.next(42)
})

observable.subscribe(console.log)
// Hello, World!
// 42

posted on 2022-07-06 12:56  aisowe  阅读(599)  评论(0编辑  收藏  举报

导航