Web 平台 API / RxJS · 从 Observable 标准契约,到它解决的那些问题 / 创建:把任何东西变成一条流 待审核 3 / 7
creation · of / from / interval / timer / fromEvent

创建:把任何东西变成一条流

有了契约那十几行 Observable,下一步就是造流。RxJS 提供一组 creation function,把现成的值、数组、Promise、定时器、DOM 事件统统包成同一种 Observable,从此都能用同一套 operator 处理。

1 · 五个 creation function

图 1-1 · 各 creator 在 marble diagram 上随时间吐值,竖线为 complete(无限流则不收尾)。可切 creator 并推进时间游标。offrom(iterable) 实际在同一 tick 内推完,图上为便于单步而分帧画。

警示 · 形态各异但契约一致。offrom(iterable) 同步逐个推、推完立即 completefrom(promise) 等 Promise resolve 后推一个值再 complete;timer 延迟一段后推一个 0 再 complete;intervalfromEvent 则永不 complete,一个按固定节奏无限计数,一个随外部事件不定时地推。无论来源如何,它们都遵守 next* (error | complete)? 这一条契约。

2 · cold 与 lazy

上面五个 creator 里,前四个是 cold 的:producer 被封存在 Observable 里,只有 subscribe 的那一刻才执行,而且每次订阅都从头重新跑一遍,两个订阅者拿到的是两次互不相干的独立执行。

fromEvent 是例外。它同样惰性——不订阅就不挂 addEventListener——但它不是 cold:按官方 glossary 的判据,cold 指「每次订阅时创建一个新的 producer」,而 fromEvent(btn, 'click') 的 producer 是那个 DOM 元素,早已存在于 subscribe 之外,两个订阅者收到的是同一串事件 [1]。惰性与冷热是两件事,fromEvent 把它们分开了。本系列在冷与热一页也把 DOM 事件划为 hot,判据一致。

图 2-1 · 一条 cold 流的每次订阅都重新掷一个随机基数再推三个值。可反复订阅,观察订阅次数与 producer 执行次数始终相等、每次收到的值各自独立。

建议 · cold 的独立执行很干净,代价是若 producer 里包着一个网络请求,每个订阅者都会各发一次。要让多个订阅者共享同一次执行(晚来的接着看而不是重跑),就得把 cold 流转成 hot 流,用 Subjectshare 做 multicast,这是冷与热一页的主题。

3 · 参考文献

  1. RxJS Documentation. Glossary and Semantics,Cold / Hot 条目. ReactiveX.