1. はじめに
このセクションは規範的ではありません。
2. コアインフラストラクチャ
2.1. Subscriber
インターフェース
[Exposed=*]interface {Subscriber undefined next (any );value undefined error (any );error undefined complete ();undefined addTeardown (VoidFunction ); // True after the Subscriber is created, up until either // complete()/error() are invoked, or the subscriber unsubscribes. Inside // complete()/error(), this attribute is true.teardown readonly attribute boolean active ;readonly attribute AbortSignal signal ; };
各 Subscriber
は 順序付き集合の 内部オブザーバを持ち、初期状態では空です。
各 Subscriber
は ティアダウンコールバックを持ち、これは リストであり、
VoidFunction
のリストで、初期値は空です。
各 Subscriber
は サブスクリプションコントローラーを持ち、
AbortController
です。
各 Subscriber
は active ブール値を持ち、初期値は true です。
注: これは、Subscriber が
クローズされてから、
所有するコールバックを二度と呼び出さないようにするための管理用変数です。
active ゲッターの手順は、this の
active ブール値を返します。
signal ゲッターの手順は、this の
サブスクリプションコントローラー の signal を返します。
next(value) メソッドの手順は以下の通りです:
-
this の 関連グローバルオブジェクト が
Windowオブジェクトであり、 その 関連付けられた Document が 完全にアクティブ でない場合、return。 -
internal observers copy を this の 内部オブザーバのコピーとする。
注: 内部オブザーバリストのコピーを作成して反復処理することで、 もし1つの 内部オブザーバの next steps が サブスクリプションを引き起こした場合でも、イテレーション中にオブザーバリストが変化しないようにしています。
-
internal observers copy の各 observer について:
-
observer の next steps を value で実行する。
注: ここで例外が投げられないのは、内部オブザーバの next steps が スクリプト提供のコールバックのラッパーの場合、process observer 手順がこれらのコールバックを呼び出す際に例外をキャッチし、グローバルに報告するロジックでラップしているためです。
next steps が仕様アルゴリズムの場合、 これらの手順はこのアサートを満たすため、例外を外部に投げません。
-
error(error) メソッドの手順は以下の通りです:
-
this の active が false なら、例外を報告し、error と this の 関連グローバルオブジェクト で、return。
-
this の 関連グローバルオブジェクト が
Windowオブジェクトであり、 その 関連付けられた Document が 完全にアクティブでない場合、return。 -
internal observers copy の各 observer について:
-
observer の error steps を error で実行する。
注: これが正しい理由については、
next()の説明を参照してください。
-
complete() メソッドの手順は以下の通りです:
-
this の 関連グローバルオブジェクト が
Windowオブジェクトであり、 その 関連付けられた Document が 完全にアクティブ でない場合、return。 -
internal observers copy の各 observer について:
-
observer の complete steps を実行する。
注: これが正しい理由については、
next()の説明を参照してください。
-
addTeardown(teardown) メソッドの手順は以下の通りです:
-
this の 関連グローバルオブジェクト が
Windowオブジェクトであり、 その 関連付けられた Document が 完全にアクティブ でない場合、return。 -
this の active が true なら、append で teardown を this の ティアダウンコールバックリストに追加する。
-
それ以外の場合は、invoke teardown を «» と "report" で呼び出す。
Subscriber
subscriber と、オプションの any
reason を受け取った場合、以下の手順を実行します:
-
subscriber の active が false なら、return。
これは再入呼び出しを防ぐためのガードです。これは「プロデューサー主導の」購読解除の場合に発生することがあります。以下の例を参照:
const outerController= new AbortController(); const observable= new Observable( subscriber=> { subscriber. addTeardown(() => { // 2.) This teardown executes inside the "Close" algorithm, while it’s // running. Aborting the downstream signal run its abort algorithms, // one of which is the currently-running "Close" algorithm. outerController. abort(); }); // 1.) This immediately invokes the "Close" algorithm, which // sets subscriber.active to false. subscriber. complete(); }); observable. subscribe({}, { signal: outerController. signal}); -
subscriber の active ブール値を false に設定する。
-
abort シグナル を subscriber の サブスクリプションコントローラー に対して reason が与えられていればそれを使って実行する。
-
subscriber の ティアダウンコールバック を 逆順で反復して各 teardown について:
-
もし subscriber の 関連グローバルオブジェクト が
Windowオブジェクトであり、その 関連付けられた Document が 完全にアクティブ でない場合は、この手順を中止する。注: この手順は繰り返し実行されます。なぜなら各 teardown が上記の
Documentを非アクティブにする可能性があるためです。 -
teardown を «» と "
report" で呼び出す。
-
2.2. Observable
インターフェース
// SubscribeCallbackは、Observableの「作成者」のコードが存在する場所です。 // subscribe()が呼び出されたときに呼び出され、新しい購読をセットアップします。callback =SubscribeCallback undefined (Subscriber );subscriber callback =ObservableSubscriptionCallback undefined (any );value dictionary {SubscriptionObserver ObservableSubscriptionCallback ;next ObservableSubscriptionCallback ;error VoidFunction ; };complete callback =ObservableInspectorAbortHandler undefined (any );value dictionary {ObservableInspector ObservableSubscriptionCallback ;next ObservableSubscriptionCallback ;error VoidFunction ;complete VoidFunction ;subscribe ObservableInspectorAbortHandler ; };abort typedef (ObservableSubscriptionCallback or SubscriptionObserver );ObserverUnion typedef (ObservableSubscriptionCallback or ObservableInspector );ObservableInspectorUnion dictionary {SubscribeOptions AbortSignal ; };signal callback =Predicate boolean (any ,value unsigned long long );index callback =Reducer any (any ,accumulator any ,currentValue unsigned long long );index callback =Mapper any (any ,value unsigned long long ); // Mapperとの違いは戻り値の型のみで、このコールバックはシーケンス内の各要素を訪問するためだけに使われ、変換はしません。index callback =Visitor undefined (any ,value unsigned long long ); // このコールバックは`any`を返し、`Observable`への変換セマンティクスを通じて`Observable`に変換される必要があります。index callback =CatchCallback any (any ); [Exposed=*]value interface {Observable constructor (SubscribeCallback );callback undefined subscribe (optional ObserverUnion = {},observer optional SubscribeOptions = {}); // valueが以下のいずれかの場合、ネイティブObservableを構築します: // - Observable // - AsyncIterable // - Iterable // - Promiseoptions static Observable from (any ); // Observableを返すオペレーター。仕様書の「Operators」セクション参照。 // // takeUntil()はpromise, iterable, async iterable, 他のobservableを消費できます。value Observable takeUntil (any );value Observable map (Mapper );mapper Observable filter (Predicate );predicate Observable take (unsigned long long );amount Observable drop (unsigned long long );amount Observable flatMap (Mapper );mapper Observable switchMap (Mapper );mapper Observable inspect (optional ObservableInspectorUnion = {});inspectorUnion Observable catch (CatchCallback );callback Observable finally (VoidFunction ); // Promiseを返すオペレーター。callback Promise <sequence <any >>toArray (optional SubscribeOptions = {});options Promise <undefined >forEach (Visitor ,callback optional SubscribeOptions = {});options Promise <boolean >every (Predicate ,predicate optional SubscribeOptions = {});options Promise <any >first (optional SubscribeOptions = {});options Promise <any >last (optional SubscribeOptions = {});options Promise <any >find (Predicate ,predicate optional SubscribeOptions = {});options Promise <boolean >some (Predicate ,predicate optional SubscribeOptions = {});options Promise <any >reduce (Reducer ,reducer optional any ,initialValue optional SubscribeOptions = {}); };options
各 Observable
は subscribe コールバックを持ち、
SubscribeCallback
または Subscriber
を受け取る一連の手順です。
各 Observable
は 弱いsubscriberを持ち、
Subscriber
への弱参照またはnullで、初期値はnullです。
注: これらの型の「ユニオン」は、
Observableが
JavaScriptで作成される場合(必ずSubscribeCallbackで構築される)と、
ネイティブに構築されたObservableオブジェクト(
subscribe コールバックが任意のネイティブ手順セットであり、JavaScriptコールバックではない場合)
の両方をサポートするためです。when()
の戻り値は後者の例です。
new
Observable(callback) コンストラクターの手順は以下の通りです:
-
this の subscribe コールバック を callback に設定する。
注: このコールバックは、後で
subscribe()が呼ばれた時に呼び出されます。
subscribe(observer, options)
メソッドの手順は:
-
Observableを購読する:this に対して observer と options を使う。
2.2.1. 補助概念
any
error を受け取り、以下の手順を実行します:
-
例外を報告:error と 現在のrealmの グローバルオブジェクト で。
注: このデフォルトを別途定義することで、
本仕様のすべてのネイティブな
Observable購読(spec proseから購読、subscribe()メソッドを経由しない場合)で
冗長な手順定義が不要になります。
- nextステップ
-
型
anyの単一パラメータを取るアルゴリズム。 初期状態では何もしない手順です。 - errorステップ
-
型
anyの単一パラメータを取るアルゴリズム。 初期状態ではデフォルトのエラーアルゴリズムです。 - completeステップ
-
パラメータなしのアルゴリズム。初期状態では何もしない手順です。
内部オブザーバの
構造体は、next,
error,
complete
コールバック関数のミラー用です。
JavaScriptからObservableの
subscribe()メソッドで購読した場合は、
これらのアルゴリズム「手順」はスクリプト提供のコールバックをラップしたものになります。
しかし、内部仕様プローズ(ユーザースクリプトではない)が
Observableを購読するときは、
これらの「手順」は任意の仕様アルゴリズムとなり、
ObserverUnion
でWeb IDL コールバック関数として提供されるものではありません。
例として§2.3.3 Promiseを返すオペレーター参照。
any
value を受け取った場合、以下の手順を実行します:
注: このアルゴリズムはWeb IDLの
from()
メソッドから分離しています。仕様プローズからWeb IDLバインディングを経由せずに値を変換できるようにするためです。
-
Type(value)が Objectでない場合は、TypeErrorを
TypeErrorで投げる。注: これはプリミティブ型がIterableに変換されること(例:String)を防ぎます。 WICG/observable#125の議論参照。
-
Observableからの変換: value の specific typeが
Observableの場合、value を返す。 -
Async Iterableからの変換: asyncIteratorMethod を ? GetMethod(value,
%Symbol.asyncIterator%) とする。注: GetMethodを使うのは、async iteratorプロトコル対応のみを調べたいからで、 実装されていない時にthrowしたくないためです。 GetIteratorは(a)プロトコル未実装、(b)実装済だがcallableでない・getterがthrowする、 両方でthrowします。GetMethodなら後者だけでthrowします。
-
asyncIteratorMethod が undefined または null なら、Iterableからの変換へジャンプ。
-
nextAlgorithm を、
Subscribersubscriber と Iterator Record iteratorRecord を受け取る以下の手順とする:-
subscriber の subscription controller の signal が abortedならreturn。
-
nextPromise を
Promiseまたはundefinedで初期値undefinedとする。 -
nextCompletion を IteratorNext(iteratorRecord)とする。
注: IteratorNextを使うのは、IteratorStepValueが iteratorの
next()が即座に値を返すobjectを期待するためですが、 async iteratorの場合はnext()がPromise/thenableを返す想定なので、Promiseでラップして値取得に反応します。 -
nextCompletionがthrow completionの場合:
-
Assert: iteratorRecordの[[Done]]はtrue。
-
nextPromiseに拒否されたpromiseで nextRecordの[[Value]]を設定。
-
-
それ以外でnextRecordがnormal completionの場合は nextPromiseに解決されたpromiseで nextRecordの[[Value]]を設定。
注: nextRecordの[[Value]]自体が すでに
Promiseでない場合に行います。 -
-
nextPromiseが値iteratorResultでfulfillされたら:
-
Type(iteratorResult) がObjectでない場合は、subscriberの
error()メソッドをTypeErrorで呼び出し、この手順を中止。 -
doneをIteratorComplete(iteratorResult)とする。
-
doneがthrow completionなら subscriberの
error()メソッドをdoneの[[Value]]で呼び出し、この手順を中止。 -
doneの[[Value]]がtrueなら、subscriberの
complete()を呼び出し、この手順を中止。 -
valueをIteratorValue(iteratorResult)とする。
-
valueがthrow completionなら subscriberの
error()メソッドをvalueの[[Value]]で呼び出し、この手順を中止。 -
subscriberの
next()をvalueの[[Value]]で呼び出す。 -
nextAlgorithmをsubscriberとiteratorRecordで再実行。
-
-
nextPromiseが理由rでrejectされたら、subscriberの
error()をrで呼び出す。
-
-
-
新しい
Observableを返す。subscribe コールバックはSubscribersubscriberを受け取り、以下の処理をするアルゴリズムとする:-
subscriberのsubscription controllerの signalが abortedならreturn。
-
iteratorRecordCompletionをGetIterator(value, async)とする。
注:
%Symbol.asyncIterator%のgetterが再度呼ばれる場合がありますが、これは極端なケースでありテスト期待値に合わせます。 詳細はissue#127の議論参照。 プロトコル自体を呼び出してIterator Recordを取得します。 -
iteratorRecordCompletionがthrow completionなら subscriberの
error()をiteratorRecordCompletionの[[Value]]で呼び出し、手順中止。注: この場合だけ、購読に同期して
error()を呼びます。他ケースではPromiseでrejectしてmicrotaskで非同期に報告します。 この同期エラー伝播は言語構造―たとえばfor-await-ofループと同様の挙動です。 -
iteratorRecordを! iteratorRecordCompletionとする。
-
Assert: iteratorRecordは Iterator Recordである。
-
subscriberのsubscription controllerの signalが abortedならreturn。
-
以下のabortアルゴリズムを追加: subscriberの subscription controllerの signalに追加:
-
AsyncIteratorClose(iteratorRecord, NormalCompletion(subscriberの subscription controllerのabort reason))
-
-
nextAlgorithmをsubscriberとiteratorRecordで実行。
-
-
Iterableからの変換: iteratorMethodを? GetMethod(value,
%Symbol.iterator%) とする。 -
iteratorMethodがundefinedなら、Promiseからの変換へジャンプ。
そうでなければ、新しい
Observableを返す。subscribe コールバックはSubscribersubscriberを受け取り、以下の手順を行うアルゴリズムとする:-
subscriberのsubscription controllerの signalが abortedならreturn。
-
iteratorRecordCompletionをGetIterator(value, sync)とする。
-
iteratorRecordCompletionがthrow completionなら subscriberの
error()をiteratorRecordCompletionの[[Value]]で呼び出し、手順中止。 -
iteratorRecordを! iteratorRecordCompletionとする。
-
subscriberのsubscription controllerの signalが abortedならreturn。
-
以下のabortアルゴリズムを追加: subscriberの subscription controllerの signalに追加:
-
IteratorClose(iteratorRecord, NormalCompletion(UNUSED))
-
-
-
next を IteratorStepValue(iteratorRecord) とする。
-
もし next が throw completion なら、 subscriber の
error()メソッドを next の [[Value]] で実行し、break する。 -
next を ! で next に設定する。
-
もし next が done なら:
-
アサート: iteratorRecord の [[Done]] は true である。
-
subscriber の
complete()を実行する。 -
Return。
-
-
subscriber の
next()を next で実行する。 -
もし subscriber の subscription controller の signal が aborted なら break する。
-
-
-
Promiseから: IsPromise(value) が true なら、
-
新しい
Observableを返す。その subscribe callback は、Subscribersubscriber を受け取り、以下を行うアルゴリズムである:-
-
もし value が v で fulfilled された場合:
-
subscriber の
next()メソッドを v で実行する。 -
subscriber の
complete()メソッドを実行する。
-
-
もし value が r で rejected された場合は、 subscriber の
error()メソッドを r で実行する。
-
-
-
ObserverUnion
または internal observer
observer と、SubscribeOptions
options を受け取り、以下の手順を実行する:
注: このアルゴリズムは Web IDL の subscribe()
メソッドから分離されており、
仕様のプローズが subscribe を Web IDL
バインディングを通さずに呼び出せるようにしている。
JavaScript によってプロパティが変更されうるオブジェクトでは、「内部」プローズは Web IDL バインディングを経由してはいけない。
§ 2.3.3 Promiseを返すオペレーター でこの使用例を参照。
-
this の 関連グローバルオブジェクト が
Windowオブジェクトで、 その 関連付けられた Document が 完全にアクティブ でない場合は return。 -
internal observer を新しい internal observer とする。
-
observer を以下のように処理する:
-
- もし observer が
ObservableSubscriptionCallbackなら -
internal observer の next steps を、
anyvalue を受け取る以下の手順に設定:-
observer を «value» と "
report" で呼び出す。
-
- もし observer が
SubscriptionObserverなら -
-
もし observer の
nextが 存在すれば、 internal observer の next steps を、anyvalue を受け取る以下の手順に設定:-
observer の next を «value» と "
report" で呼び出す。
-
-
もし observer の
errorが 存在すれば、 internal observer の error steps を、anyerror を受け取る以下の手順に設定:-
observer の error を «error» と "
report" で呼び出す。
-
-
もし observer の
completeが 存在すれば、 internal observer の complete steps を以下の手順に設定:-
observer の complete を «» と "
report" で呼び出す。
-
-
- もし observer が internal observer なら
- internal observer を observer に設定する。
- もし observer が
-
-
アサート: internal observer の error steps は デフォルトの error アルゴリズム か、
errorコールバック関数を呼び出すアルゴリズムである。 -
this の weak subscriber が null でなく、かつ this の weak subscriber の active が true なら:
-
subscriber を this の weak subscriber とする。
-
internal observer を subscriber の internal observers に追加する。
-
-
もし options の
signalが aborted なら、 internal observer を subscriber の internal observers から削除する。 -
それ以外の場合は、以下の abort アルゴリズム を options の
signalに追加する:-
もし subscriber の active が false なら、この手順を中止する。
-
internal observer を subscriber の internal observers から削除する。
-
もし subscriber の internal observers が 空なら、 subscriber を close する。 options の
signalの abort reason を使う。
-
-
-
Return。
-
-
subscriber を 新しい
Subscriberとする。 -
internal observer を subscriber の internal observers に追加する。
-
this の weak subscriber を subscriber に設定する。
-
-
もし options の
signalが aborted なら、 subscriber を close する options のsignalの abort reason を使う。 -
それ以外の場合は 以下の abort アルゴリズム を options の
signalに追加する:-
もし subscriber の active が false なら、この手順を中止する。
-
internal observer を subscriber の internal observers から削除する。
-
もし subscriber の internal observers が 空なら、 subscriber を close する。 options の
signalの abort reason を使う。
-
-
-
もし this の subscribe callback が
SubscribeCallbackなら、 subscriber を «subscriber» と "rethrow" で呼び出す。もし 例外 E が投げられた場合は、 subscriber の
error()を E で呼び出す。 -
それ以外の場合は this の subscribe callback の手順を subscriber で実行する。
2.3. オペレーター
現時点では https://github.com/wicg/observable#operators を参照してください。
2.3.1. from()
from(value) メソッドの手順は以下の通りです:
-
value を
Observableに変換した結果を返す。例外があれば再スローする。
2.3.2.
Observableを返すオペレーター
takeUntil(value) メソッドの手順は以下の通りです:
-
sourceObservable を this とする。
-
notifier を value を
Observableに変換した結果とする。 -
observable を 新しい
Observableとし、その subscribe callback はSubscribersubscriber を受け取るアルゴリズムである:このメソッドは2つのObservableにsubscribeすることを伴います。 (1) notifier、(2) sourceObservable。次の状況で両方の購読を解除します:-
notifier が値("next" または "error")の発行を開始した場合、この場合は notifier から購読解除します。 必要な情報を得たので、これ以上値を発行し続ける必要がありません。同時に sourceObservable からも購読解除します。 なぜなら、observable への購読を手動で終了するため、sourceObservable の値を observable に送る必要がなくなるためです。
-
sourceObservable が
error()またはcomplete()を自ら実行した場合、この場合は notifier から購読解除します。 なぜなら observable が sourceObservable の値をミラーする必要がなくなったためです。 sourceObservable の購読解除は不要です、なぜなら自ら完了したためです。
-
notifierObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
subscriber の
complete()メソッドを実行する。注: これにより sourceObservable の購読も解除されます。 これは sourceObservable が "外側" subscriber の subscription controller の signal で購読されているためです。 この signal は上記または下記で subscriber の
complete()が呼ばれると abort されます。 - error steps
-
subscriber の
complete()メソッドを実行する。
注: notifier
Observableが自ら complete した場合は subscriber を complete する必要はありません。 この場合 observable は sourceObservable を継続してミラーし続けます。 -
options を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
notifier に notifierObserver と options でsubscribeする。
-
subscriber の active が false なら、return。
注: notifier が同期的に値を発行した場合、sourceObservable の subscribe callback は一度も呼ばれません。 ただし notifier が同期的に complete のみした場合は、subscriber の active は true のままなので、sourceObservable への購読が行われ、observable は途切れることなくミラーします。
-
sourceObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
渡された value を使って subscriber の
next()メソッドを実行する。 - error steps
-
渡された error を使って subscriber の
error()メソッドを実行する。 - complete steps
-
subscriber の
complete()メソッドを実行する。
注: sourceObserver は基本的にパススルーであり、sourceObservable の発行するすべてをミラーします。 ただし sourceObservable が notifier より先に完了した場合は notifier から購読を解除します。
-
sourceObservable に sourceObserver と options でsubscribeする。
-
-
observable を返す。
map(mapper) メソッドの手順は以下の通りです:
-
sourceObservable を this とする。
-
observable を 新しい
Observableとし、その subscribe callback はSubscribersubscriber を受け取るアルゴリズムである:-
idx を
unsigned long long、初期値0とする。 -
sourceObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
-
mapper を «渡された value, idx» と "
rethrow" で呼び出し、返り値を mappedValue とする。もし 例外 E が投げられた場合は、 subscriber の
error()メソッドを E で実行し、この手順を中止する。 -
idx をインクリメントする。
-
subscriber の
next()メソッドを mappedValue で実行する。
-
- error steps
-
渡された error で subscriber の
error()メソッドを実行する。 - complete steps
-
subscriber の
complete()メソッドを実行する。
-
options を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
sourceObservable に sourceObserver と options で subscribe する。
-
-
observable を返す。
filter(predicate) メソッドの手順は以下の通りです:
-
sourceObservable を this とする。
-
observable を 新しい
Observableとし、その subscribe callback はSubscribersubscriber を受け取るアルゴリズムである:-
idx を
unsigned long long、初期値0とする。 -
sourceObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
-
predicate を «渡された value, idx» と "
rethrow" で呼び出し、返り値を matches とする。もし 例外 E が投げられた場合は、 subscriber の
error()メソッドを E で実行し、この手順を中止する。 -
idx を idx + 1 に設定する。
-
もし matches が true なら、subscriber の
next()メソッドを value で実行する。
-
- error steps
-
渡された error で subscriber の
error()メソッドを実行する。 - complete steps
-
subscriber の
complete()メソッドを実行する。
-
options を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
sourceObservable に sourceObserver と options で subscribe する。
-
-
observable を返す。
take(amount) メソッドの手順は以下の通りです:
-
sourceObservable を this とする。
-
observable を 新しい
Observableとし、その subscribe callback はSubscribersubscriber を受け取るアルゴリズムである:-
remaining を amount とする。
-
もし remaining が 0 なら、subscriber の
complete()メソッドを実行し、この手順を中止する。 -
sourceObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
-
渡された value で subscriber の
next()メソッドを実行する。 -
remaining をデクリメントする。
-
もし remaining が 0 なら、subscriber の
complete()メソッドを実行する。
-
- error steps
-
渡された error で subscriber の
error()メソッドを実行する。 - complete steps
-
subscriber の
complete()メソッドを実行する。
-
options を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
sourceObservable に sourceObserver と options で subscribe する。
-
-
observable を返す。
drop(amount) メソッドの手順は以下の通りです:
-
sourceObservable を this とする。
-
observable を 新しい
Observableとし、その subscribe callback はSubscribersubscriber を受け取るアルゴリズムである:-
remaining を amount とする。
-
sourceObserver を新しい internal observer とし、次のように初期化する:
- next steps
- error steps
-
渡された error で subscriber の
error()メソッドを実行する。 - complete steps
-
subscriber の
complete()メソッドを実行する。
-
options を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
sourceObservable に sourceObserver と options で subscribe する。
-
-
observable を返す。
flatMap(mapper) メソッドの手順は以下の通りです:
-
sourceObservable を this とする。
-
observable を 新しい
Observableとし、その subscribe callback はSubscribersubscriber を受け取るアルゴリズムである:-
idx を
unsigned long long、初期値0とする。 -
outerSubscriptionHasCompleted を boolean、初期値 false とする。
-
queue を新しい list(
any型値)、初期値は空とする。注: queue は observable が直前に subscribe された
Observableがまだ完了していない間に sourceObservable から発行されるObservableを保存するために使われます。 -
activeInnerSubscription を boolean、初期値 false とする。
-
sourceObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
-
もし activeInnerSubscription が true なら:
-
queue に value を追加する。
注: この value は、現在 subscribe 中の
Observableが 完了した後に処理されます。
-
-
それ以外の場合:
-
activeInnerSubscription を true に設定する。
-
flatmap process next value steps を value, subscriber, mapper、そして 参照として queue, activeInnerSubscription, outerSubscriptionHasCompleted, idx で実行する。
注: この flatmap process next value steps は value から導出された
Observableに subscribe し、 その購読が非アクティブになるまで値を処理し続けます(エラーまたは完了)。"inner" のObservableが完了した場合、 処理手順は queue の次の値で再帰的に自分自身を呼び出します。値が 存在しない 場合、処理手順は終了し、 activeInnerSubscription の設定を解除し、 sourceObservable から発行される将来の値が正しく処理されるようにします。
-
-
- error steps
-
渡された error で subscriber の
error()メソッドを実行する。 - complete steps
-
-
outerSubscriptionHasCompleted を true にする。
注: activeInnerSubscription が true の場合、下記の手順では subscriber を complete しません。 その場合は flatmap process next value steps が、 "inner" の購読が非アクティブになった後、queue が 空であれば subscriber を complete する責任を持ちます。
-
activeInnerSubscription が false かつ queue が 空なら、subscriber の
complete()メソッドを実行する。
-
-
options を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
sourceObservable に sourceObserver と options で subscribe する。
-
-
observable を返す。
any
value、Subscriber
subscriber、Mapper
mapper、および次の参照を受け取る:list型
any
値の queue、boolean の activeInnerSubscription、boolean
の outerSubscriptionHasCompleted、unsigned long long
の idx の場合、次の手順を実行する:
-
mappedResult を mapper を «value, idx» と "
rethrow" で呼び出した結果とする。もし 例外 E が投げられた場合は、 subscriber の
error()メソッドを E で実行し、この手順を中止する。 -
idx を idx + 1 に設定する。
-
innerObservable を
from()を mappedResult で呼び出した結果とする。もし 例外 E が投げられた場合は、 subscriber の
error()メソッドを E で実行し、この手順を中止する。from()を直接呼び出すべきではありません。例外を適切に処理する内部アルゴリズムを呼び出し、subscriber にパイプしたいです。 -
innerObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
渡された value で subscriber の
next()メソッドを実行する。 - error steps
-
渡された error で subscriber の
error()メソッドを実行する。 - complete steps
-
-
queue が空でなければ:
-
nextValue を queue の先頭要素とし、remove で queue から削除する。
-
flatmap process next value steps を nextValue、subscriber、mapper、 参照として queue、activeInnerSubscription で実行する。
-
-
それ以外の場合:
-
activeInnerSubscription を false に設定する。
注: activeInnerSubscription は参照型なので、 以降 "outer" の
Observable(sourceObservable)から発行される値が正しく処理されます。 -
outerSubscriptionHasCompleted が true なら、 subscriber の
complete()メソッドを実行する。注: "outer"
Observableが完了しているが、 まだ subscriber を complete していません。これは、まだ完了していない "inner" のObservable(つまり innerObservable)が キューに存在していたためです。今まさに完了したということです。
-
-
-
innerOptions を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
innerObservable に innerObserver と innerOptions で subscribe する。
switchMap(mapper) メソッドの手順は以下の通りです:
-
sourceObservable を this とする。
-
observable を 新しい
Observableとし、その subscribe callback はSubscribersubscriber を受け取るアルゴリズムである:-
idx を
unsigned long long、初期値0とする。 -
outerSubscriptionHasCompleted を boolean、初期値 false とする。
-
activeInnerAbortController を
AbortControllerまたは null、初期値 null とする。注:
AbortControllerはこのアルゴリズムの next steps のみで新しい値が代入され、 null になるのは switchmap process next value steps で "inner"Observableが完了またはエラーになった時です。現在 "inner" の購読があるかどうかの判定に使います。"complete steps" も参照します。 -
sourceObserver を新しい internal observer とし、次のように初期化する:
-
- next steps
-
-
activeInnerAbortController が null でなければ、 signal abort する。
注: これにより前回の値から導出された "inner"
Observableから購読解除される。 すぐに新しい値から導出された "inner"Observableに購読する。 -
activeInnerAbortController を 新しい
AbortControllerに設定する。 -
switchmap process next value steps を value、subscriber、mapper、参照として activeInnerAbortController、outerSubscriptionHasCompleted、idx で実行する。
注: switchmap process next value steps は、 value から導出される
Observableに subscribe し、 その購読が非アクティブになる(エラー/完了)か、activeInnerAbortController が abort されるまで値を処理します。
-
- error steps
-
渡された error で subscriber の
error()メソッドを実行する。 -
- complete steps
-
-
outerSubscriptionHasCompleted を true に設定する。
注: activeInnerAbortController が null でない場合、直ちに subscriber を complete しない。 その場合は switchmap process next value steps が inner の購読が完了した時点で subscriber を complete する。
-
activeInnerAbortController が null なら、subscriber の
complete()メソッドを実行する。
-
-
-
options を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
sourceObservable に sourceObserver と options で subscribe する。
-
-
observable を返す。
any
value、Subscriber
subscriber、Mapper
mapper、および次の参照を受け取る:AbortController
activeInnerAbortController、boolean
の outerSubscriptionHasCompleted、
unsigned long long
の idx の場合、次の手順を実行する:
-
mappedResult を mapper を «value, idx» と "
rethrow" で呼び出した結果とする。もし 例外 E が投げられた場合は、 subscriber の
error()メソッドを E で実行し、この手順を中止する。 -
idx を idx + 1 に設定する。
-
innerObservable を
from()を mappedResult で呼び出した結果とする。もし 例外 E が投げられた場合は、 subscriber の
error()メソッドを E で実行し、この手順を中止する。 -
innerObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
渡された value で subscriber の
next()メソッドを実行する。 - error steps
-
渡された error で subscriber の
error()メソッドを実行する。注: この時点で activeInnerAbortController を null にする必要はありません。 なぜなら subscriber の
error()を呼び出すことで "outer" の Observable から購読解除されるため、以降値が push されることはありません。 - complete steps
-
-
outerSubscriptionHasCompleted が true なら、 subscriber の
complete()メソッドを実行する。 -
それ以外の場合は activeInnerAbortController を null に設定する。
注: この変数は参照型なので、 switchMap complete steps に "inner" の購読がないことを知らせます。
-
-
innerOptions を新しい
SubscribeOptionsとし、signalは、create a dependent abort signal を «activeInnerAbortController の signal、subscriber の subscription controller の signal»、AbortSignal、 current realm で生成したものとする。 -
innerObservable に innerObserver と innerOptions で subscribe する。
inspect(inspectorUnion) メソッドの手順は以下の通りです:
-
subscribe callback を
VoidFunctionもしくは null(初期値 null)とする。 -
next callback を
ObservableSubscriptionCallbackもしくは null(初期値 null)とする。 -
error callback を
ObservableSubscriptionCallbackもしくは null(初期値 null)とする。 -
complete callback を
VoidFunctionもしくは null(初期値 null)とする。 -
abort callback を
ObservableInspectorAbortHandlerもしくは null(初期値 null)とする。 -
inspectorUnion を次のように処理する:
- もし inspectorUnion が
ObservableSubscriptionCallbackなら -
-
next callback を inspectorUnion に設定する。
-
- もし inspectorUnion が
ObservableInspectorなら
- もし inspectorUnion が
-
sourceObservable を this とする。
-
observable を 新しい
Observableとし、 その subscribe callback はSubscribersubscriber を受け取るアルゴリズムである:-
subscribe callback が null でなければ、invoke で «» と "
rethrow" で呼び出す。もし 例外 E が投げられた場合は、 subscriber の
error()メソッドを E で実行し、この手順を中止する。注: この結果、sourceObservable は決して subscribe されません。
-
abort callback が null でなければ、subscriber の subscription controller の signal に次の abort algorithm を追加する:
-
abort callback を «subscriber の subscription controller の signal の abort reason» と "
report" で呼び出す。
-
-
sourceObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
-
next callback が null でなければ、 next callback を «渡された value» と "
rethrow" で呼び出す。もし 例外 E が投げられた場合:
-
abort callback を subscriber の subscription controller の signal から削除する。
注: abort callback は consumer-initiated の解除だけに使うため、プロデューサーによるエラーや完了時は呼ばれないようにする必要があります。
Chromiumの実装と一致していますが、もともと渡された
SubscribeOptionsのsignalへの参照を保持し、その abort 時だけ abort callback を呼び出すべきかも。要調査。 -
subscriber の
error()メソッドを E で実行し、この手順を中止する。
-
-
渡された value で subscriber の
next()メソッドを実行する。
-
- error steps
-
-
abort callback を subscriber の subscription controller の signal から削除する。
-
error callback が null でなければ、 error callback を «渡された error» と "
rethrow" で呼び出す。もし 例外 E が投げられた場合は、 subscriber の
error()メソッドを E で実行し、この手順を中止する。 -
渡された error で subscriber の
error()メソッドを実行する。
-
- complete steps
-
-
abort callback を subscriber の subscription controller の signal から削除する。
-
complete callback が null でなければ、 complete callback を «» と "
rethrow" で呼び出す。もし 例外 E が投げられた場合は、 subscriber の
error()メソッドを E で実行し、この手順を中止する。 -
subscriber の
complete()メソッドを実行する。
-
-
options を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
sourceObservable に sourceObserver と options で subscribe する。
-
-
observable を返す。
catch(callback) メソッドの手順は以下の通りです:
-
sourceObservable を this とする。
-
observable を 新しい
Observableとし、 その subscribe callback はSubscribersubscriber を受け取るアルゴリズムである:-
sourceObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
渡された value で subscriber の
next()メソッドを実行する。 - error steps
-
-
callback を «渡された error» と "
rethrow" で呼び出し、 返り値を result とする。もし 例外 E が投げられた場合は、 subscriber の
error()を E で実行し、この手順を中止する。 -
innerObservable を
from()を result で呼び出した結果とする。もし 例外 E が投げられた場合は、 subscriber の
error()メソッドを E で実行し、この手順を中止する。from()を直接呼び出すべきではありません。例外を適切に処理する内部アルゴリズムを呼び出し、subscriber にパイプしたいです。 -
innerObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
渡された value で subscriber の
next()メソッドを実行する。 - error steps
-
渡された error で subscriber の
error()メソッドを実行する。 - complete steps
-
subscriber の
complete()メソッドを実行する。
-
innerOptions を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
innerObservable に innerObserver と innerOptions で subscribe する。
注: innerObservableへのsubscribeは sourceObservableから購読解除せず安全に実施可能です。なぜなら error steps 内で呼ばれるので sourceObservable の購読は既に完了しています。
-
- complete steps
-
subscriber の
complete()メソッドを実行する。
-
options を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
sourceObservable に sourceObserver と options で subscribe する。
-
-
observable を返す。
finally(callback) メソッドの手順は以下の通りです:
-
sourceObservable を this とする。
-
observable を 新しい
Observableとし、 その subscribe callback はSubscribersubscriber を受け取るアルゴリズムである:-
subscriber の
addTeardown()メソッドを callback で実行する。 -
sourceObserver を新しい internal observer とし、次のように初期化する:
- next steps
-
渡された value で subscriber の
next()メソッドを実行する。 - error steps
-
-
渡された error で subscriber の
error()メソッドを実行する。
-
- complete steps
-
-
subscriber の
complete()メソッドを実行する。
-
-
options を新しい
SubscribeOptionsとし、signalは subscriber の subscription controller の signal とする。 -
sourceObservable に sourceObserver と options で subscribe する。
-
-
observable を返す。
2.3.3.
Promiseを返すオペレーター
toArray(options) メソッドの手順は以下の通りです:
-
p を新しい promiseとする。
-
options の
signalが null でない場合:-
options の
signalが aborted なら:-
p を options の
signalの abort reason で reject する。 -
p を返す。
-
-
abort algorithm を options の
signalに追加:-
p を options の
signalの abort reason で reject する。
注: ここでは p を reject するだけです。this
Observableの購読も自動的にcloseされます。"inner" Subscriberが closeされるためです。 -
-
-
values を新しい listとする。
-
observer を新しい internal observer とし、次のように初期化:
- next steps
-
渡された value を values に追加する。
- error steps
-
p を渡された error で reject する。
- complete steps
-
p を values で resolve する。
-
this に observer と options で subscribe する。
-
p を返す。
forEach(callback, options)
メソッドの手順は以下の通りです:
-
p を新しい promiseとする。
-
visitor callback controller を新しい
AbortControllerとする。 -
internal options を新しい
SubscribeOptionsとし、signalは dependent abort signal(visitor callback controller の signal、options のsignal(nullでなければ))で生成する。AbortSignal、 current realm を使う。多くの trivial な internal observer は値をチェーンに流すだけで購読を制御しません。 このオペレーターでは下記 observer の next steps が callback が例外を投げた場合、基礎となる購読を abort する責任を持ちます。なので "Observableへのsubscribe" に渡す
SubscribeOptionsのsignalは options の signal と、かつAbortSignalを持つAbortControllerの dependent signal にする必要がある。 -
internal options の
signalが aborted なら:-
p を internal options の
signalの abort reason で reject する。 -
p を返す。
-
-
abort algorithm を internal options の
signalに追加:-
p を internal options の
signalの abort reason で reject する。注: p の reject は internal options の signal に結び付けられています。 options の signal の abort時の microtaskが先にキューされ、p の reject handler より先に実行されます。
-
-
idx を
unsigned long long(初期値0)とする。 -
observer を新しい internal observer とし、次のように初期化:
- next steps
-
-
callback を «渡された value, idx» と "
rethrow" で呼び出す。もし 例外 E が投げられた場合は、 p を E で reject し、visitor callback controller を E で abort する。
-
idx をインクリメントする。
-
- error steps
-
p を渡された error で reject する。
- complete steps
-
this に observer と internal options で subscribe する。
-
p を返す。
every(predicate, options)
メソッドの手順は以下の通りです:
-
p を新しい promiseとする。
-
controller を新しい
AbortControllerとする。 -
internal options を新しい
SubscribeOptionsとし、signalは dependent abort signal(controller の signal、options のsignal(nullでなければ))で生成する。AbortSignal、 current realm を使う。 -
internal options の
signalが aborted なら:-
p を internal options の
signalの abort reason で reject する。 -
p を返す。
-
-
abort algorithm を internal options の
signalに追加:-
p を internal options の
signalの abort reason で reject する。
-
-
idx を
unsigned long long(初期値0)とする。 -
observer を新しい internal observer とし、次のように初期化:
- next steps
-
-
predicate を «渡された value, idx» と "
rethrow" で呼び出し、返り値を passed とする。もし 例外 E が投げられた場合は、 p を E で reject し、controller を E で abort する。
-
idx を idx + 1 に設定する。
-
passed が false なら p を false で resolve し、controller を abort する。
-
- error steps
-
p を渡された error で reject する。
- complete steps
-
p を true で resolve する。
-
this に observer と internal options で subscribe する。
-
p を返す。
first(options)
メソッドの手順は以下の通りです:
-
p を新しい promiseとする。
-
controller を新しい
AbortControllerとする。 -
internal options を新しい
SubscribeOptionsとし、signalは dependent abort signal(controller の signal、options のsignal(nullでなければ))で生成する。AbortSignal、 current realm を使う。 -
internal options の
signalが aborted なら:-
p を internal options の
signalの abort reason で reject する。 -
p を返す。
-
-
abort algorithm を internal options の
signalに追加:-
p を internal options の
signalの abort reason で reject する。
-
-
internal observer を新しい internal observer とし、次のように初期化:
- next steps
-
-
p を渡された value で resolve する。
-
controller を abort する。
-
- error steps
Reject p を渡された error で拒否する。
- complete steps
-
p を新しい
RangeErrorで reject する。注: これは、ソース
Observableが 1つも値を発行する前に complete した場合のみ到達します。
-
this に internal observer と internal options で subscribe する。
-
p を返す。
last(options)
メソッドの手順は以下の通りです:
-
p を新しい promiseとする。
-
options の
signalが null でない場合:-
options の
signalが aborted なら:-
p を options の
signalの abort reason で reject する。 -
p を返す。
-
-
abort algorithm を options の
signalに追加:-
p を options の
signalの abort reason で reject する。
-
-
-
lastValue を
anyまたは null(初期値 null)とする。 -
hasLastValue を boolean(初期値 false)とする。
-
observer を新しい internal observer とし、次のように初期化:
- next steps
-
-
hasLastValue を true に設定する。
-
lastValue を渡された value に設定する。
-
- error steps
-
p を渡された error で reject する。
- complete steps
-
-
hasLastValue が true なら p を lastValue で resolve する。
-
それ以外なら p を新しい
RangeErrorで reject する。注:
first()の注を参照。
-
-
-
this に observer と options で subscribe する。
-
p を返す。
find(predicate, options)
メソッドの手順は以下の通りです:
-
p を新しい promiseとする。
-
controller を新しい
AbortControllerとする。 -
internal options を新しい
SubscribeOptionsとし、signalは dependent abort signal(controller の signal、options のsignal(nullでなければ))で生成する。AbortSignal、 current realm を使う。 -
internal options の
signalが aborted なら:-
p を internal options の
signalの abort reason で reject する。 -
p を返す。
-
-
abort algorithm を internal options の
signalに追加:-
p を internal options の
signalの abort reason で reject する。
-
-
idx を
unsigned long long(初期値0)とする。 -
observer を新しい internal observer とし、次のように初期化:
- next steps
-
-
predicate を «渡された value, idx» と "
rethrow" で呼び出し、返り値を passed とする。もし 例外 E が投げられた場合は、 p を E で reject し、controller を E で abort する。
-
idx を idx + 1 に設定する。
-
passed が true なら p を value で resolve し、controller を abort する。
-
- error steps
-
p を渡された error で reject する。
- complete steps
-
this に observer と internal options で subscribe する。
-
p を返す。
some(predicate, options)
メソッドの手順は以下の通りです:
-
p を新しい promiseとする。
-
controller を新しい
AbortControllerとする。 -
internal options を新しい
SubscribeOptionsとし、signalは dependent abort signal(controller の signal、options のsignal(nullでなければ))で生成する。AbortSignal、 current realm を使う。 -
internal options の
signalが aborted なら:-
p を internal options の
signalの abort reason で reject する。 -
p を返す。
-
-
abort algorithm を internal options の
signalに追加:-
p を internal options の
signalの abort reason で reject する。
-
-
idx を
unsigned long long(初期値0)とする。 -
observer を新しい internal observer とし、次のように初期化:
- next steps
-
-
predicate を «渡された value, idx» と "
rethrow" で呼び出し、返り値を passed とする。もし 例外 E が投げられた場合は、 p を E で reject し、controller を E で abort する。
-
idx を idx + 1 に設定する。
-
passed が true なら p を true で resolve し、controller を abort する。
-
- error steps
-
p を渡された error で reject する。
- complete steps
-
p を false で resolve する。
-
this に observer と internal options で subscribe する。
-
p を返す。
reduce(reducer, initialValue, options)
メソッドの手順は以下の通りです:
-
p を新しい promiseとする。
-
controller を新しい
AbortControllerとする。 -
internal options を新しい
SubscribeOptionsとし、signalは dependent abort signal(controller の signal、options のsignal(nullでなければ))で生成する。AbortSignal、 current realm を使う。 -
internal options の
signalが aborted なら:-
p を internal options の
signalの abort reason で reject する。 -
p を返す。
-
-
abort algorithm を internal options の
signalに追加:-
p を internal options の
signalの abort reason で reject する。
-
-
idx を
unsigned long long(初期値0)とする。 -
accumulator を initialValue(与えられていれば)で初期化し、なければ未初期化とする。
-
observer を新しい internal observer とし、次のように初期化:
- next steps
-
-
accumulator が未初期化(つまり initialValue が渡されていない)なら、 accumulator を渡された value に設定し、idx を idx + 1 にし、この手順を中止する。
注: この場合 reducer は this が最初に出す
currentValueでは呼ばれません。 2つ目以降の値が発行されたとき、reducer をその値(currentValue)と 最初の値(accumulator)で呼び出します。 -
reducer を «accumulator(
accumulator), 渡された value(currentValue), idx(index)»と "rethrow" で呼び出し、返り値を result とする。もし 例外 E が投げられた場合は、 p を E で reject し、controller を E で abort する。
-
idx を idx + 1 に設定する。
-
accumulator を result に設定する。
-
- error steps
-
p を渡された error で reject する。
- complete steps
-
this に observer と internal options で subscribe する。
-
p を返す。
3. EventTarget
統合
dictionary {ObservableEventListenerOptions boolean =capture false ;boolean ; };passive partial interface EventTarget {Observable when (DOMString ,type optional ObservableEventListenerOptions = {}); };options
when(type, options) メソッドの手順は以下の通りです:
-
this の 関連グローバルオブジェクト が
Windowオブジェクトで、その 関連付けられた Document が 完全にアクティブ でない場合は return。 -
event target を this とする。
-
observable を 新しい
Observableとし、次のように初期化する:- subscribe callback
-
Subscribersubscriber を受け取るアルゴリズムで、次の手順を実行する:-
event target が null なら、この手順を中止する。
注: event target は購読時点で ガベージコレクションされている可能性を考慮しています。
-
subscriber の subscription controller の signal が aborted なら、この手順を中止する。
-
event listener を追加する。対象は event target、 event listener は次の通り:
- type
-
type
- callback
-
新しい Web IDL
EventListenerインスタンスを生成し、1引数のEvent型 event を受け取る関数への参照とする。この関数は observable event listener invoke algorithm を subscriber と event で実行する。 - capture
-
options の
capture - passive
- once
-
false
- signal
-
subscriber の subscription controller の signal
注: event listener は subscription controller の signal が aborted になった時 必ずクリーンアップされます(エンジンの所有モデルによらず)。
-
-
observable を返す。
Subscriber
subscriber と
Event
event を受け取り、次の手順を実行する:
-
subscriber の
next()メソッドを event で実行する。
4. セキュリティとプライバシーに関する考慮事項
この内容は explainer から本仕様へのアップストリーム中です。現時点では以下のリソースを参照できます:
5. 謝辞
特に Ben Lesh に感謝します。Observable
API の設計に多大な貢献をいただき、長年にわたりユーザーランド Observable コードをメンテナンスしてきたことが
Webプラットフォームへの貢献を可能にしました。