rxdart 0.23.0-dev.1 rxdart: ^0.23.0-dev.1 copied to clipboard
RxDart is an implementation of the popular reactiveX api for asynchronous programming, leveraging the native Dart Streams api.
RxDart #
About #
RxDart is a library for working with Streams of data.
Dart comes with a very decent Streams API out-of-the-box; rather than attempting to provide an alternative to this API, RxDart adds functionality from the reactive extensions specification on top of it.
If you are familiar with Observables from other languages, please see the Rx Observables vs Dart Streams comparison chart for notable distinctions between the two.
How To Use RxDart #
For Example: Reading the Konami Code #
import 'package:rxdart/rxdart.dart';
void main() {
const konamiKeyCodes = const <int>[
KeyCode.UP,
KeyCode.UP,
KeyCode.DOWN,
KeyCode.DOWN,
KeyCode.LEFT,
KeyCode.RIGHT,
KeyCode.LEFT,
KeyCode.RIGHT,
KeyCode.B,
KeyCode.A,
];
final result = querySelector('#result');
document.onKeyUp
.map((event) => event.keyCode)
.bufferCount(10, 1) // An extension method provided by rxdart
.where((lastTenKeyCodes) => const IterableEquality<int>().equals(lastTenKeyCodes, konamiKeyCodes))
.listen((_) => result.innerHtml = 'KONAMI!');
}
API Overview #
RxDart adds functionality to Dart Streams in two ways:
- Stream Classes - create Streams with specific capabilities, such as combining or merging many Streams together.
- Extension Methods - transform a source Stream into a new Stream with different capabilities, such as throttling events.
Stream Classes #
The Stream class provides different ways to create a Stream: Stream.fromIterable
or Stream.periodic
, for example. RxDart provides additional Stream classes for a variety of tasks, such as combining or merging Streams together!
You can construct the Streams provided by RxDart in two ways. The following examples are equivalent in terms of functionality:
- Instantiating the Stream class directly.
- Example:
final myStream = MergeStream([myFirstStream, mySecondStream]);
- Example:
- Using the
Observable
class' factory constructors, which are useful for discovering which types of Streams are provided by RxDart.- Example:
final myStream = Observable.merge([myFirstStream, mySecondStream]);
- Example:
List of Classes / Helper Factories
- ConcatStream / Observable.concat
- ConcatEagerStream / Observable.concatEager
- DeferStream / Observable.defer
- Observable.just
- MergeStream / Observable.merge
- NeverStream / Observable.never
- RaceStream / Observable.race
- RepeatStream / Observable.repeat
- RetryStream / Observable.retry
- RetryWhenStream / Observable.retryWhen
- SequenceEqualStream / Observable.sequenceEqual
- SwitchLatestStream / Observable.switchLatest
- TimerStream / Observable.timer
- CombineLatestStream (combineLatest2, combineLatest... combineLatest9) / Observable.combineLatest
- ForkJoinStream (forkJoin2, forkJoin... forkJoin9) / Observable.forkJoin
- RangeStream / Observable.range
- ZipStream (zip2, zip3, zip4, ..., zip9) / Observable.zip
Extension Methods #
The extension methods provided by RxDart can be used on any Stream
. They convert a source Stream into a new Stream with additional capabilities, such as buffering or throttling events.
Example
final myStream = Stream.fromIterable([1, 2, 3]).debounceTime(Duration(seconds: 1));
List of Extension Methods
- buffer / BufferStreamTransformer
- bufferCount / BufferStreamTransformer / onCount
- bufferTest / BufferStreamTransformer / onTest
- bufferTime / BufferStreamTransformer / onTime
- concatMap (alias for
asyncExpand
) - concatWith
- debounce / DebounceStreamTransformer
- debounceTime / DebounceStreamTransformer
- delay / DelayStreamTransformer
- dematerialize / DematerializeStreamTransformer
- distinctUnique / DistinctUniqueStreamTransformer
- doOnCancel / DoStreamTransformer
- doOnData / DoStreamTransformer
- doOnDone / DoStreamTransformer
- doOnEach / DoStreamTransformer
- doOnError / DoStreamTransformer
- doOnListen / DoStreamTransformer
- doOnPause / DoStreamTransformer
- doOnResume / DoStreamTransformer
- exhaustMap / ExhaustMapStreamTransformer
- flatMap / FlatMapStreamTransformer
- flatMapIterable
- groupBy / GroupByStreamTransformer
- interval / IntervalStreamTransformer
- mapTo / MapToStreamTransformer
- materialize / MaterializeStreamTransformer
- mergeWith
- max / StreamMaxFuture
- min / StreamMinFuture
- onErrorResume / OnErrorResumeStreamTransformer
- onErrorResumeNext / OnErrorResumeStreamTransformer
- onErrorReturn / OnErrorResumeStreamTransformer
- onErrorReturnWith / OnErrorResumeStreamTransformer
- sample / SampleStreamTransformer
- sampleTime / SampleStreamTransformer
- scan / ScanStreamTransformer
- skipUntil / SkipUntilStreamTransformer
- startWith / StartWithStreamTransformer
- startWithMany / StartWithManyStreamTransformer
- switchMap / SwitchMapStreamTransformer
- takeUntil / TakeUntilStreamTransformer
- timeInterval / TimeIntervalStreamTransformer
- timestamp / TimestampStreamTransformer
- throttle / ThrottleStreamTransformer
- throttleTime / ThrottleStreamTransformer
- whereType / WhereTypeStreamTransformer
- window / WindowStreamTransformer
- windowCount / WindowStreamTransformer / onCount
- windowTest / WindowStreamTransformer / onTest
- windowTime / WindowStreamTransformer / onTime
- withLatestFrom / WithLatestFromStreamTransformer
- zipWith
Rx Observables vs Dart Streams #
In many situations, Streams and Observables work the same way. However, if you're used to standard Rx Observables, some features of the Stream api may surprise you. We've included a table below to help folks understand the differences.
Additional information about the following situations can be found by reading the Observable class documentation.
Situation | Rx Observables | Dart Streams |
---|---|---|
An error is raised | Observable Terminates with Error | Error is emitted and Stream continues |
Cold Observables | Multiple subscribers can listen to the same cold Observable, each subscription will receive a unique Stream of data | Single subscriber only |
Hot Observables | Yes | Yes, known as Broadcast Streams |
Is {Publish, Behavior, Replay}Subject hot? | Yes | Yes |
Single/Maybe/Complete ? | Yes | No, uses Dart Future |
Support back pressure | Yes | Yes |
Can emit null? | Yes, except RxJava | Yes |
Sync by default | Yes | No |
Can pause/resume a subscription*? | No | Yes |
Examples #
Web and command-line examples can be found in the example
folder.
Web Examples #
In order to run the web examples, please follow these steps:
- Clone this repo and enter the directory
- Run
pub get
- Run
pub run build_runner serve example
- Navigate to http://localhost:8080/web/ in your browser
Command Line Examples #
In order to run the command line example, please follow these steps:
- Clone this repo and enter the directory
- Run
pub get
- Run
dart example/example.dart 10
Flutter Example #
Install Flutter
In order to run the flutter example, you must have Flutter installed. For installation instructions, view the online documentation.
Run the app
- Open up an Android Emulator, the iOS Simulator, or connect an appropriate mobile device for debugging.
- Open up a terminal
cd
into theexample/flutter/github_search
directory- Run
flutter doctor
to ensure you have all Flutter dependencies working. - Run
flutter packages get
- Run
flutter run
Notable References #
Changelog #
Refer to the Changelog to get all release notes.