📘
時間のかかる処理が終わるまで待ってから結果を返す、終わってたらすぐに返す
ユースケース
- 画面A の開始時に、時間のかかるデータ読み込みを開始する
- 画面A でなんやかんや操作した後、画面B へ移動
- 画面B では Aで読み込んだデータが必要なので、読み込みが完了するまで待つ
実現方法
readonly data$ = new BehaviorSubject<string[]>(undefined);
// 画面Aで時間のかかるデータ読み込み
setTimeout(() => {
this.data$.next(['a', 'b', 'c'])
}, 1000);
// すぐに画面Bへ移動した場合、読み込み完了まで待つ
firstValueFrom(this.data$.pipe(filter(x => x != null))).then(x => {
console.log('a', x);
});
// 読み込みが終わってから画面Bへ移動した場合、すぐに結果を返す
setTimeout(() => {
firstValueFrom(this.data$.pipe(filter(x => x != null))).then(x => {
console.log('b', x);
});
}, 2000);
書いてみるとなんの事はなく、BehaviourSubject と Observable→Promise 変換を使えば簡単だった。
BehaviourSubject は「最新の結果を保持し、subscribe されたらそれを通知する」という特性があるので、BehaviourSubject を Promise 化すると、すぐに結果が返される。
ここで初期値(undefined
)を無視すれば、「何らかの値が通知されたら結果を返却するPromise」 になる。
Discussion