Secara default, observable akan memanggil generatornya untuk setiap pelanggan dan mengeluarkan semua nilai yang dihasilkan oleh generator tersebut. Jadi misalnya:
let obs = Observable.create { observer in
for each in [1, 2, 3, 5, 7, 11] {
observer.onNext(each)
}
observer.onCompleted()
}
(Perhatikan bahwa di atas adalah implementasi dari Observable.from(_:)
)
Setiap kali sesuatu berlangganan obs
, penutupan dipanggil dan keenam acara berikutnya akan diterima. Inilah yang dikenal sebagai cold observable, dan sekali lagi ini merupakan perilaku default. Asumsikan Observable dingin kecuali Anda mengetahui sebaliknya.
Ada juga konsep hot observable. Observable panas tidak memanggil fungsi generatornya ketika sesuatu berlangganan padanya.
Berdasarkan pertanyaan Anda, dan komentar Anda selanjutnya, sepertinya Anda ingin tahu cara membuat suhu dingin menjadi panas... Cara mendasarnya adalah dengan memanggil .multicast
(atau salah satu operator yang menggunakan implementasinya seperti publish()
, replay(_:)
atau replayAll()
.) Ada juga operator tujuan khusus yang disebut .share()
yang akan memanaskan observasi dan menjaganya tetap panas sampai semua pelanggan berhenti berlangganan (kemudian akan menjadi dingin lagi.) Dan tentu saja, Subjek dianggap panas karena tidak' tidak memiliki fungsi generator untuk dipanggil.
Namun perlu diperhatikan, bahwa banyak observasi yang memiliki perilaku sinkron, ini berarti bahwa observasi tersebut akan memancarkan semua nilainya segera setelah sesuatu berlangganan dan dengan demikian sudah selesai sebelum pengamat lain (di thread tersebut) memiliki kesempatan untuk berlangganan.
Beberapa contoh lagi... .interval(_:scheduler:)
adalah pengamatan dingin dengan perilaku asinkron. Katakanlah Anda memiliki yang berikut ini:
let i = Observable<Int>.interval(.seconds(3), scheduler: MainScheduler.instance)
i.subscribe(onNext: { print($0, "from first") })
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
i.subscribe(onNext: { print($0, "from second") })
}
Apa yang akan Anda temukan adalah setiap pengamat akan mendapatkan aliran nilai independennya sendiri (keduanya akan dimulai dengan 0) karena generator di dalam interval
dipanggil untuk kedua pengamat. Jadi Anda akan melihat output seperti:
0 from first
1 from first
0 from second
2 from first
1 from second
3 from first
2 from second
Jika Anda melakukan multicast interval, Anda akan melihat perilaku yang berbeda:
let i = Observable<Int>.interval(.seconds(3), scheduler: MainScheduler.instance)
.publish()
i.subscribe(onNext: { print($0, "from first") })
i.connect()
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
i.subscribe(onNext: { print($0, "from second") })
}
Hal di atas akan menghasilkan:
0 from first
1 from first
1 from second
2 from first
2 from second
3 from first
3 from second
(Perhatikan bahwa detik dimulai dengan 1, bukan 0.) Operator berbagi akan bekerja dengan cara yang sama dalam kasus ini kecuali Anda tidak perlu memanggil connect()
karena operator tersebut melakukannya secara otomatis.
Terakhir, hati-hati. Jika Anda memublikasikan observasi sinkron, Anda mungkin tidak mendapatkan apa yang Anda harapkan:
let i = Observable.from([1, 2, 3, 5])
.publish()
i.subscribe(onNext: { print($0, "from first") })
i.connect()
i.subscribe(onNext: { print($0, "from second") })
menghasilkan:
1 from first
2 from first
3 from first
5 from first
Karena kelima peristiwa (empat peristiwa berikutnya dan peristiwa yang selesai) muncul segera setelah connect()
dipanggil sebelum pengamat kedua mendapat kesempatan untuk berlangganan.
Artikel yang mungkin membantu Anda adalah Observable Panas dan Dingin tetapi cukup canggih...
person
Daniel T.
schedule
01.11.2020
ReplaySubject.createUnbounded()
dan masalahnya akan hilang. Entah itu, atau sesuaikan pertanyaannya untuk menunjukkan masalah sebenarnya yang Anda alami. - person Daniel T.   schedule 30.10.2020