← RxJS · 从 Observable 标准契约,到它解决的那些问题 / 坐标系:function / Iterator / Promise / Observable 待审核 2 / 7
four-kinds · 标准坐标系 2×2

坐标系:function / Iterator / Promise / Observable

JavaScript 里「拿到一个值」的方式,可以放进一张 2×2 的坐标系:一个轴是值的个数singular 单值 / plural 多值),另一个轴是谁主导取值pull 消费者主动拉 / push 生产者主动推)。四个格子,恰好对上四种熟悉的接口。Observable 不是凭空冒出来的新概念,它填的正是右下角那格——多值 + push

点下面网格里的任意一格,右侧用能跑的代码演示它的取值方式。默认停在 Observable 这格:它是 Promise 在「多值」维度上的自然推广,也是 TC39 Observable proposal 与 WHATWG DOM Observable(el.when('click'))想标准化的形状。

1 · 四者放在一起对照

同一张坐标系换个角度看:决定一个接口落在哪一格的,就是下面这四个属性。pull 一列由消费者掌握节奏(你调用才有值);push 一列由生产者掌握节奏(值就绪了推给你)。从上到下,值的个数从一个变成任意多个。

接口 求值时机 值的个数 谁主导 能否取消
function 同步,调用即返回 单值 消费者拉(pull) —(瞬时完成)
Iterator 同步,逐个惰性求值 多值 消费者拉(pull) 停止 next() 即可
Promise 异步,就绪后一次 单值 生产者推(push) 不能取消
Observable 异步,随时间陆续 多值 生产者推(push) unsubscribe 取消

Observable = 多值版的 Promise。 Promise 在「push」这一列,但只 resolve 一个值;把「单值」放宽成「多值」,同一列往下走一格,得到的正是 Observable——一个能随时间推任意多个值、并且可取消的生产者。它为什么惰性、如何用 next / error / complete 推值、怎样 unsubscribe 收尾,见 契约;怎样把 DOM 事件、定时器、Promise 包成 Observable,见 创建