Web 平台 API / 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。

它不是凭空冒出来的新概念。TC39 Observable proposal 与 WICG 的 DOM Observable 提案(EventTarget.when())要标准化的正是这个形状;后者仍是实验特性,仅 Chromium 135+(2025-04)落地,Firefox 与 Safari 均未实现(兼容性据 MDN BCD,核对于 2026-08)。

1 · 四格网格

图 1-1 · 2×2 网格的四格与各自的取值接口。可点任一格看能跑的代码,默认停在 Observable 那格。

2 · 四者的属性对照

决定一个接口落在哪一格的是下面这四个属性。pull 一列由消费者掌握节奏,调用才有值;push 一列由生产者掌握节奏,值就绪了就推出来。从上到下,值的个数从一个变成任意多个。

「能否取消」一列是这张表里差异最大的:拉取方停手即可,而推送方需要生产者本身提供退出机制。
接口 求值时机 值的个数 谁主导 能否取消
function 同步,调用即返回 单值 消费者拉(pull) —(瞬时完成)
Iterator 同步,逐个惰性求值 多值 消费者拉(pull) 停止调 next() 即可
Promise 异步,就绪后一次 单值 生产者推(push) 不能取消
Observable 异步,随时间陆续 多值 生产者推(push) unsubscribe 取消

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