Stream di Dart adalah aliran berkelanjutan dari data yang mengalir dari satu sumber ke sumber lainnya. Dalam konteks Flutter, stream digunakan untuk mengelola aliran data asynchronous, memungkinkan aplikasi untuk merespons perubahan data secara dinamis tanpa memblokir main thread. Stream cocok digunakan untuk sebuah operasi yang membutuhkan update data secara terus menerus seperti contoh pemutaran suara yang mengupdate durasi setiap detik nya. dengan kata lain Stream adalah salah satu implementasi dari Reactive Programming di Flutter yang mana terdapat variable yang digunakan untuk mengirimkan data dan ada variabel yang menerima data sebagai Subscriber
Mari kita lihat contoh sederhana penggunaan stream di Flutter untuk memahami konsepnya dengan lebih baik.
import 'dart:async';
void main() {
final myStreamController = StreamController<int>();
final myStreamSubscription = myStreamController.stream.listen((event) {
print('Data baru diterima: $event');
});
myStreamController.add(1);
myStreamController.add(2);
myStreamController.add(3);
myStreamSubscription.cancel();
myStreamController.close();
}
Dalam contoh di atas, kita membuat sebuah stream controller dan sebuah stream subscription. Kemudian, kita mengirimkan beberapa data ke stream menggunakan add()
, dan sebuah Subsriber yang membaca perubahan menggunakan stream.listen()
, yang mana pada console akan tercetak “Data baru diterima: 1”, “Data baru diterima: 2”, “Data baru diterima: 3”, sesuai dengan kode yang ada di dalam method listen. lalu method cancel()
adalah untuk menghentikan stream subscriber jika diperlukan, dan method close()
pada Stream Controller untuk menutup Stream Controller agar tidak terjadi memory leak.
Kesalahan dalam penggunaan Stream
terkadang hal yang paling sering dialami developer dalam penggunaan Stream adalah Error “Stream already subscribed to”. ini dikarenakan ada 2 method listen() yang me-listen satu StreamController, hal ini tidak diperbolehkan. tapi jika kita memerlukan hal tersebut kita bisa menggunakan Broadcast Stream.
Sebuah broadcast stream adalah jenis stream yang memungkinkan untuk memiliki beberapa subscription dan setiap subscriber akan menerima setiap data yang dipancarkan tanpa tergantung pada langganan lainnya. Ini berbeda dengan single subscription stream yang hanya mengizinkan satu subscriber untuk seluruh siklus hidup stream.
Berikut adalah contoh penggunaan stream.broadcast()
beserta fungsinya:
import 'dart:async';
void main() {
StreamController<int> controller = StreamController<int>.broadcast();
StreamSubscription<int> subscription1 = controller.stream.listen((value) {
print('Subscriber 1 menerima nilai: $value');
});
StreamSubscription<int> subscription2 = controller.stream.listen((value) {
print('Subscriber 2 menerima nilai: $value');
});
controller.add(1);
controller.add(2);
controller.add(3);
subscription1.cancel();
subscription2.cancel();
controller.add(4);
controller.add(5);
controller.close();
}
Dalam contoh di atas, kita membuat sebuah broadcast stream dengan StreamController<int>.broadcast()
. Kemudian, kita membuat dua langganan (subscription) ke stream tersebut. Setiap langganan akan menerima nilai yang ditambahkan ke dalam stream. Setelah itu, kita membatalkan langganan pertama dan kedua. Meskipun langganan telah dibatalkan, kita masih dapat menambahkan nilai ke dalam stream dan nilai tersebut akan diterima oleh langganan lainnya. Terakhir, kita menutup (close) controller stream setelah selesai digunakan.