Saya ingin bisa menunggu yang bisa diamati, misalnya
const source = Rx.Observable.create(/* ... */)
//...
await source;
Upaya naif menghasilkan menunggu penyelesaian segera dan tidak memblokir eksekusi
Edit: Pseudocode untuk kasus penggunaan lengkap saya adalah:
if (condition) {
await observable;
}
// a bunch of other code
Saya mengerti bahwa saya dapat memindahkan kode lain ke fungsi lain yang terpisah dan meneruskannya ke panggilan balik berlangganan, tetapi saya berharap dapat menghindarinya.
javascript
rxjs
ecmascript-7
MurahSteaks
sumber
sumber
.subscribe()
pemanggilan metode?Jawaban:
Anda harus berjanji
await
. Ubah acara berikutnya yang dapat diamati menjadi janji dan tunggu itu.Edit catatan: Jawaban ini awalnya menggunakan .take (1) tetapi diubah menjadi menggunakan .first () yang menghindari masalah Promise yang tidak pernah terselesaikan jika streaming berakhir sebelum nilai muncul.
sumber
await observable.first().toPromise();
?first()
akan mengakibatkan penolakan, dantake(1)
akan mengakibatkan janji tertunda.take(1)
ataufirst()
dalam kasus seperti ini. Karena Anda mengharapkan tepat SATU peristiwa terjadi, Anda harus menggunakansingle()
yang akan memunculkan pengecualian jika ada lebih dari 1, sementara tidak melempar pengecualian jika tidak ada. Jika ada lebih dari satu kemungkinan ada sesuatu yang salah dalam kode / model data Anda dll. Jika Anda tidak menggunakan tunggal Anda akan berakhir dengan sewenang-wenang memilih item pertama yang kembali tanpa peringatan bahwa ada lebih banyak. Anda harus berhati-hati dalam predikat pada sumber data upstream untuk selalu menjaga urutan yang sama.import 'rxjs/add/operator/first';
Sepertinya harus begitu
Seperti yang dicatat dalam komentar sebelumnya, ada perbedaan substansial antara operator
take(1)
danfirst()
ketika ada observasi selesai kosong.Observable.empty().first().toPromise()
akan mengakibatkan penolakan denganEmptyError
yang dapat ditangani sesuai, karena memang tidak ada nilainya.Dan
Observable.empty().take(1).toPromise()
akan menghasilkan resolusi denganundefined
nilai.sumber
take(1)
akan menghasilkan janji yang menunggu. Itu akan menghasilkan janji yang diselesaikan dengan .undefined
Anda perlu
await
janji, jadi Anda ingin menggunakantoPromise()
. Lihat ini untuk detail lebih lanjut tentangtoPromise()
.sumber
Jika
toPromise
tidak berlaku lagi untuk Anda, Anda dapat menggunakan.pipe(take(1)).toPromise
tetapi seperti yang Anda lihat di sini , ini tidak usang.Jadi tolong gunakan saja
toPromise
(RxJs 6) seperti yang dikatakan:async / await contoh:
Baca lebih lanjut di sini .
Dan tolong hapus klaim yang salah ini mengatakan
toPromise
tidak berlaku lagi.sumber