typescript - Observable zincirlerken RxJs basamakları
Typescript'te aşağıdaki gibi görünen async/await sözdizimi ile Promise kullanıyordum
const fooData = await AsyncFooData();
const barData = await AsyncBarData();
... do something with fooData and barData
Bunu RxJs Observable<T> ile yaparsam benim için şöyle bir şey oluyor
AsyncFooData().subscribe(fooData => {
AsyncBarData().subscribe(barData => {
... do something with fooData and barData
})
})
Bunu yapmanın daha iyi bir yolu var mı? Çünkü daha fazla AsyncData ile çalışmam gerekirse, bu hızlı ama okunaklı olmaktan uzak hale geliyor, merdiven basamağı gibi.
Cevap #1
async/await ile yaptığınız şeyi tam olarak yapamayacaksınız çünkü hâlâ .subscribe geri aramasına sahip olmanız gerekiyor ve birden fazla özelliğin yayılma olasılığı var. .subscribe çağrılarını hiçbir zaman iç içe kullanmamalısınız. Genellikle mergeMap gibi daha yüksek düzeyli bir Observable operatörü veya combineLatest gibi birden fazla Observable’ın yayımını senkronize eden bir Observable oluşturucu kullanırsınız:
combineLatest(AsyncFooData(), AsyncBarData()).subscribe([fooData, barData] => {
});
İhtiyacınız olan kesin işlev, kendi ihtiyaçlarınıza ve foo ile bar'ın nasıl yaydığına bağlıdır:
combineLatest- Herhangi bir kaynak veri yaydığında yayım yapar (not: yayın yapmaya başlamadan önce tüm kaynakların en az bir kez yayım yapmış olması gerekir).zip- Yayılımları senkronize eder, örneğin, her Observable bir kez yayım yaptığında bir kez, sonra iki kez vb. yayım yapar.forkJoin- Tüm kaynak gözlemlenebilirler tamamlandığında yayın yaparmerge- Herhangi bir kaynak yayınladığında tetiklenir. Yukarıdakiler gibi çıktıları birleştirmez.
Daha fazlası mevcut: https://www.learnrxjs.io/operators/combination/
Cevap #2
Bence birden fazla asenkron işlemi daha 'temiz' bir şekilde zincirlemeye çalışıyorsunuz. Ben şunu yapıyorum:
AsyncFooData'nın bir promise döndürdüğünü varsaydığım içinfrom()'u kullandım. Eğer Observable döndürüyorsa, sadecefrom()'u kaldırın.- birden fazla abonelikten kaçının (genellikle düşündüğümüzden daha az sıklıkta).
pipe()kullanarak uygun operatörleri zincirleyin, ihtiyacınız olduğu kadar, oldukça düz bir şekilde.subscribe(), tüm işlemler tamamlandığında çağrılır.- Style A, foo’dan gelen sonucu subscribe’ın sonraki fonksiyonuna kadar iletir.
- Stil B yalnızca son asenkron işlemin sonucu ile çalışır.
Not: Bu örnekler, IDE sözdizimi kontrolü olmadan kavram/yaklaşımı paylaşmak için yazılmıştır. Kavram çalışmalıdır ancak eğer sözdizimi hataları varsa özür dilerim.
// A: if you need both foo and bar
from(AsyncFooData()).pipe(
concatMap(foo => AsyncBarData().pipe(
map(bar => ({foo, bar})
)),
tap(val => console.log(val), // chain more operators here...
).subscribe(({foo, bar}) => {
// do stuff with foo and bar
})
// B: if foo is only used to get bar (i.e. no need to pass it along)
from(AsyncFooData()).pipe(
concatMap(foo => AsyncBarData(foo)), // assume foo is only used to get bar
tap(val => console.log(val), // chain more operators here...
).subscribe(bar => {
// do stuff with bar
})
