坐标系: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 · 四格网格
2 · 四者的属性对照
决定一个接口落在哪一格的是下面这四个属性。pull 一列由消费者掌握节奏,调用才有值;push 一列由生产者掌握节奏,值就绪了就推出来。从上到下,值的个数从一个变成任意多个。
| 接口 | 求值时机 | 值的个数 | 谁主导 | 能否取消 |
|---|---|---|---|---|
function |
同步,调用即返回 | 单值 | 消费者拉(pull) | —(瞬时完成) |
Iterator |
同步,逐个惰性求值 | 多值 | 消费者拉(pull) | 停止调 next() 即可 |
Promise |
异步,就绪后一次 | 单值 | 生产者推(push) | 不能取消 |
Observable |
异步,随时间陆续 | 多值 | 生产者推(push) | unsubscribe 取消 |
建议 · 把 Promise 的「单值」放宽成「多值」,在 push 一列往下走一格,得到的就是 Observable:一个能随时间推任意多个值、并且可取消的生产者。它为什么惰性、如何用 next / error / complete 推值、怎样 unsubscribe 收尾,见契约;怎样把
DOM 事件、定时器、Promise 包成 Observable,见创建。