RxJS’e yakından bakış -2: Subjects

0 1,752

Bu yazıda RxJS’in özel bir Observable türü olan Subject’e yakından bakacağız. Subject, nedir? ne işe yarar? hırlı mıdır? hırsız mıdır? Hepsini bu yazının sonunda öğrenmiş olacağız.

Bir Önceki Yazılara ulaşmak için burayı tıklayınız

https://bilisim.io/2019/10/08/rxjse-merhaba-deyin/

https://bilisim.io/2019/10/20/rxjse-yakindan-bakis-1-observables/

Subject, birbirinden bağımsız Observer’lara verileri yaymak(multicast) için kullanılan tiptir. Observable’ler varsayılan olarak tek bir observer’a verileri yayar(unicast).

Observable’ı şu şekilde düşünebiliriz. Yazılım takım liderinizin, yazdığınız kodda çıkan hata yüzünden size bağırmasıdır. Burada Yazılım takım lideri observable, siz ise observer’ınızdır.

Subject’i ise şu şekilde düşünebiliriz. Yazılım takım liderinizin ekibinin yaptığı işi beğenmeyerek tüm takıma aynı anda bağırması gibidir. Burada yazılım takım lideri Subject, takım üyeleri birbirinden bağımsız oberver’dır.

Her subject bir observable’dır. Var olan bir subject’e yayılan değerleri almak için bir observer ile abone olabilirsiniz. Observer açısından baktığınızda kendisine gelen verilerin, tek noktaya yayın yapan bir observable’dan mı yoksa subject’ten mi gelip gelmediği bilenemez. Subject’te bulunan subscribe fonksiyonu cağrıldığında, veri sağlayan yeni bir yürütme çağırmaz. Kendisine verilen observer’ı, Observer’ların listesine kayıt eder.

Her subject bir observer’dır. İçinde next(v)error(e) ve complete() metotları olan bir nesnedir. Subject’e yeni bir değer sağlamak için next(deger) metodunu çağırın ve bu sağlanan yeni değer, kendisini dinlemek için kayıt olan observer’lara iletilecektir(multicasted).

Aşağıdaki örnekte Subject’e eklenen iki adet observer bulunmaktadır. Subject’i bir kaç yeni değer ile besliyoruz. https://stackblitz.com/edit/rxjs-subject-1?devtoolsheight=100

Subject aynı zamanda bir observer olduğu için, Bir observable’a yapılan her hangi bir abonelik işleminde subject’i argüman verebilirsiniz. Aşağıdaki örnekte bunu görebilirsiniz. https://stackblitz.com/edit/rxjs-subject-2?devtoolsheight=100

Yukarıdaki örnekte, tek bir observer’a yayın yapan observable’ı, çok noktaya yayın yapan bir duruma getirmiş olduk. Bir nevi Observable, subject’e dönüştü diyebiliriz.

Kendi alanında uzman 3 farklı Subject türü mevcuttur. Bunlar: BehaviorSubjectReplaySubject ve AsyncSubject.

Observables Radyo : FM 103.1

Multicasted Observable: Birden çok aboneye sahip olan Subject’e bildirimleri iletir.

Multicasted Observable: Birden çok observer’a, aynı observable değerini göstermek için bir Subject kullanır.

Aşağıdaki örnekte multicast operatörü ile bu işlemin nasıl yapıldığını görebilirsiniz.  https://stackblitz.com/edit/t3xwp5?devtoolsheight=100

Yukarıdaki örnekğin çalışma mantığı şu şekildedir: Observerlar, Subject’e abone olur, Subject’e kaynak Observable’a abone olur.

multicast fonksiyonu; Abonelik işlemine başlandığında, Subject gibi davranan bir Observable’a döner. multicast fonksiyonu içinde connect() metodu barındıran “ConnectableObservable” tipinde bir observable döner.

connect() metodu,paylaşılan Observable çalışmasının, tam olarak ne zaman başlayacağını belirlemek için önemlidir. connect() metodu çağırıldığında aslında içeride source.subscribe(subject) çağrılmaktadır. connect() bir Subscription döndüğünden abonelikten çıkma(unsubscribe) işlemi yapılabilir.

connect() metodunu manüel olarak çağırmak ve abonelik işlemleriyle uğraşmak genellikle zor ve uğraştırıcıdır.

Aşağıdaki örnekte connect() manüel çağrılıp, işi biten observer’lar için unsubcribe işlemleri açıktan yapılıyor. https://stackblitz.com/edit/hakawv?devtoolsheight=100

Yukarıdaki örneğimizde her bir saniyede bir değer üreten source observable’ını ve bir adet subject yaratıp; multicast operatörünü kullanarak multicasted observable’ını yaratıyoruz . Daha sonra akış sırası şu şekilde oluyor:

  1. Birinci observer olan subscripton1multicasted Observable’ına abone olur.
  2. multicasted Observable’ı subscriptionConnect değişkeni ile connect() metodu çağrılarak yayına başlar.
  3. Bir saniye sonra 0 değeri subscripton1 için sunulur.
  4. İkinci observer olan subscripton2, iki saniye sonra multicasted Observable’ına abone olur.
  5. 1 değeri subscripton1 ve subscripton2 observerlarına sunulur.
  6. Yayın başladıktan dört saniye sonra subscripton1 yayından ayrılır
  7. 2 değeri sadece subscripton2 ye sunulur.
  8. Yayın başladıktan dört saniye sonra subscripton2 de yayından ayrılır.
  9. subscriptionConnect observable’ı unscribe yapılarak yayın sonlandırılır.

Yukarıdaki işlemlerin otomatik olması için refCountoperatörü yardımımıza koşar. Aşağıdaki örneği inceleyelim: https://stackblitz.com/edit/zgg3qd?devtoolsheight=100

Yukarıdaki örnekte ilk abone yayına dahil olur olmaz, yayın otomatik olarak başlıyor. En son abone yayından çıkınca, yayın otomatik olarak bitirilir.

BehaviorSubject

BehaviorSubject; şimdiki/geçerli değer kavramına sahip olan bir subject türüdür. En son yayılan değeri hafızada tutar. Yeni bir Observer abonelik yapınca bu değer anında BehaviorSubject aboneye iletilir. BehaviorSubject, yaratılırken bir başlangıç değeri alır.

BehaviorSubjects, zaman içindeki değerleri temsil etmek için kullanışlıdır. Örneğin, doğum günlerinin bir olay akışı Subject’tir, ancak bir kişinin yaş akışı bir BehaviorSubject olacaktır.

https://stackblitz.com/edit/vma4rn?devtoolsheight=100

Yukarıdaki örnekte sıfır başlangıç değeri ile “BehaviorSubject” yaratılıyor. Daha sonra birinci observer, subject’e abone oluyor. 1 ve 2 değerleri birinci observer’a sunuluyor. Süreç başladıktan bir saniye sonra ikinci observer, subject’e abone oluyor ve anında 2 değeri kendisine sunuluyor. Süreç başladıktan iki saniye sonra 3 değeri her iki observer’a sunuluyor.

ReplaySubject

ReplaySubject; BehaviorSubject’le benzer işi yapmaktadır. BehaviorSubject son değeri yeni katılan aboneye sunarken, ReplaySubject ise yaratılırken kendisine verilen hafızada tutulacak değer sayısı kadar değeri yeni aboneye iletir.  https://stackblitz.com/edit/8xpxmi?devtoolsheight=100

Yukarıdaki örnekte sadece son üç değeri tutacak şekilde bir ReplaySubject yaratılıyor. İlk observer abonelik yaptıktan sonra 1,2,3,4 değerleri kendisine sunuluyor. Süreç başladıktan iki saniye sonra ikinci observer abonelik işlemi yapıyor. kendisine 23,4 değerleri anında sunuluyor. Süreç başladıktan üç saniye sonra 5 değeri her iki observer’a sunuluyor.

AsyncSubject

Süreç tamamlandıktan sonra en son değeri tüm observer’lara gönderen bir Subject türüdür.  https://stackblitz.com/edit/95xh7d?devtoolsheight=100

Yukarıdaki örnekte yaratılan AsyncSubject’e ilk observer abone olduktan sonra 12,3 ve 4 değerleri üretiliyor. Daha sonra ikinci observer abone olduktan sonra, 5 değeri üretilip complete() metodu çağrılıyor. Bu işlemin sonunda sadece 5 değeri her iki obserbver’a sunuluyor.

KAYNAK:

Email adresiniz yayınlanmayacaktır.