web-dev-qa-db-ja.com

観察可能な非同期と同期

Observableプロデューサーが非同期または同期であるかどうかを確認するにはどうすればよいですか?

同期の例:

Observable.of([1, 2, 3])

別の非同期の例(ngrxストア、 ここ を参照)

this.store.take(1);

そして今、明らかな非同期の例:

this.http.get(restUrl)

これがどのように機能するか、そして一部のObservableは同期可能であり、他は非同期である可能性があることを完全に理解しています。私が理解していないのは、どのようにして事前に違いを知ることができるかということです。たとえば、プロデューサーに非同期になることを通知する明らかなインターフェイスはありますか?

tl; dr

この質問が出てきた主な理由は、上記のリンク( ここ )からの回答によるものです。 @Sasxaは、同期呼び出しを使用してngrxストアから最新の値を取得できると(正しく)回答しました。

function getState(store: Store<State>): State {
    let state: State;

    store.take(1).subscribe(s => state = s);

    return state;
}

しかし、オブザーバブルは通常非同期であることを知っていたので、私はこれを見てすぐにRACE CONDITIONを考えました!サブスクライブが関数をコールバックする前に、メソッドが未定義の値を返す可能性があります。

StoreとObservableの内部をデバッグしましたが、この例は確かに同期していますが、どうすればそれを知ることができますか? ngrxを知っている人にとって、selectstoreメソッド(最新の値を取得するために使用される)は間違いなく非同期です。これがリアクティブGUIを提供するためです。私がやったと思い込んだ。

これは、Icannot上記のコードを次のようにリファクタリングできないことを意味します。

function getLatest(observable: Observable): any {
    let obj: any;

    observable.take(1).subscribe(latest => obj = latest);

    return obj;
}

これは任意のObservableで呼び出すことができ、同期プロデューサーでも機能します。非同期プロデューサーでも機能する場合がありますが、非同期observableが渡された場合、これは間違いなく競合状態です。

6
Forge_7

取得するオブザーバブルが同期であるか非同期であるかを判断するのは困難です(サードパーティライブラリからオブザーバブルが返されると想像してください)。そのため、実行順序が制御され、予測可能な方法で記述します。

また、concat、combineLatest、forkjoin、switchMap、race、mergeなどの演算子があり、さまざまなシナリオに適した順序とパフォーマンスを得るのに役立ちます。

3
Fan Cheung

非同期スケジューラ(Scheduler.asyncまたはScheduler.asap)で直接スケジュールされているかどうかを確認して、オブザーバブルが非同期であるかどうかを判断できます。 、foo$.schedulerとして公開されています:

let schedulers = [null, Scheduler.asap];
let randomScheduler = schedulers[~~(Math.random()*2)]
let foo$ = Observable.of('foo', randomScheduler);

この情報は、foo$がさらに処理されると、さらに利用できなくなります。他の演算子とチェーンされています。

また、値が同期的に(同じティックで)生成されるのか、非同期的に生成されるのかを判断することは不可能です。これは、観察可能な内部に依存するためです。

let foo$ = new Observable(observer => {
  if (~~(Math.random()*2))
    setTimeout(() => observer.next('foo'));
  else
    observer.next('foo');
});

TL; DR:これを確実に知ることは不可能です

6
Estus Flask