2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Observableの本質:Promiseとの違いとpush-based設計

Posted at

概要

JavaScriptの非同期といえば、Promiseasync/await が広く使われている。
だが Rx の中核である Observable は、それらとは根本的に性質が異なる。

本稿では、PromiseとObservableの決定的な違い
そしてなぜ「push-based設計」が非同期処理の破綻を防ぐ鍵となるのかを、設計構造と振る舞いから明快に解き明かす。


1. ObservableとPromiseの対比

特性 Promise Observable
値の数 一度きりの「単一値」 0回〜無限回の「複数値」
実行タイミング 作成時に即実行 subscribe() されるまで遅延評価
キャンセル可能性 不可(外部制御できない) unsubscribe() で明示的に停止可能
同期 vs 非同期 必ず非同期 同期・非同期の両方に対応
構成/合成の容易さ then() チェーン 豊富なオペレータで関数的に合成可能

2. Promiseの本質:pull-basedな単一処理

const p = new Promise((resolve) => {
  console.log("start")
  resolve(42)
})

p.then((v) => console.log("resolved", v))
  • Promise「1回きりの非同期イベント」
  • 実行は定義と同時then() に関係なく)

3. Observableの本質:push-basedなストリーム

import { Observable } from 'rxjs'

const obs = new Observable<number>((subscriber) => {
  subscriber.next(1)
  subscriber.next(2)
  subscriber.complete()
})

obs.subscribe((v) => console.log('Received:', v))
  • Observable値の発行者
  • 観測者が購読しない限り実行されない(=遅延評価)

4. push vs pull:設計思想の対比

✅ pull型(Promise):

  • 消費者側が「必要なタイミングで値を取りに行く」
  • モデル:const x = getValue()

✅ push型(Observable):

  • 発行者側が「値を流す」、消費者はそれを観測する
  • モデル:onValue(x => doSomething(x))

この違いは、制御権がどちらにあるかに直結する。
→ イベントストリームや非同期の流れはpushの方が自然


5. 実用的差分:キャンセルと制御

❌ Promiseの不可避な非同期

const p = new Promise((resolve) => {
  setTimeout(() => resolve('done'), 3000)
})

// キャンセルできない。止められない。

✅ Observableの制御可能な非同期

import { interval } from 'rxjs'

const obs = interval(1000)

const sub = obs.subscribe((v) => console.log('tick', v))

setTimeout(() => sub.unsubscribe(), 4000) // 4秒で止める

→ Observableは購読解除が可能
→ アニメーション、UIイベント、リアルタイム通信において致命的な差となる


6. 実装モデルで見る違い

// Promiseは即時実行、変更できない
const p = new Promise(() => console.log("実行された"))

// Observableは subscribe されるまで何も起きない
const o = new Observable(() => console.log("観測された"))

「定義 = 実行」ではない構造が、Rxの柔軟性の源


よくある誤解と対策

❌ ObservableはPromiseの高機能版

→ ✅ 異なる概念。Observableはイベント・時間を統合したストリーム処理モデル


❌ async/awaitで十分

→ ✅ 確かに簡単。しかし、継続的・複数の非同期処理には限界がある
→ UI入力、WebSocket、監視処理などではRx的構造が不可欠


❌ Rxは覚えることが多すぎる

→ ✅ 最初に必要なのはpush/pullの思想の違いだけ。演算子は構造が分かれば覚える必要なし


結語

Observableは「非同期を扱う構造の一つ」ではない。
時間・状態・イベントを“構造化されたストリーム”として設計する哲学そのものである。

  • Promise が「未来の1つの値」だとすれば
  • Observable は「未来に流れ続ける情報の川」である

リアクティブ設計とは、
“非同期の断片をつなぎ合わせ、秩序あるストリームとして設計に組み込むことで、制御不能な非同期を掌握するアーキテクチャである。”

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?