Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

sequence

Stream and Future are core apis provided by Dart: Async, both built to handle asynchronous events. Today we’re going to focus on Stream. A Stream is a sequence of asynchronous events, understood as an asynchronous Iterable. The difference is that when you fetch the next event from Iterable, it will give it to you immediately. A Stream will tell you when it is ready.

How to understandStream

In development, the Stream is treated as a factory machine:

  • It has a portal that can receive instructions (data), and the machine doesn’t know when the portal will put something in
  • Data processing can be carried out inside the machine according to instructions (transformation layer, also can be made logic layer)
  • It has an exit, and when the internal instructions are done, the product will come out of that, and we don’t know when the product will come out of that exit

Two types of workflows

  • Type 1: GoStreamSend data instruction
  • Type 2: Custom transformation layer, listeningStream

How to useStream?

> createStream

Here, the editor introduces four common ways to create streams in development

1. Create a vm periodically every secondstreamData is sent within the stream1 ~ 15, the use oftake(15)There is a limit to polling 15 times

var stream = Stream<int>.periodic(const Duration(seconds: 1), (value) => value).take(15);
Copy the code

2. Create a vm based on the existing data source

var stream = new Stream<int>.fromIterable([1.2.3.4.5]);
Copy the code

3. Create from zero and useyieldKeyword, this way is more commonly used,BlocThat’s how it’s used

// The simulation injects data into the stream every second
Stream<int> createStream(int maxCount) async* {
  int i = 0;
  while (true) {
    await Future.delayed(Duration(seconds: 1));
    yield i++;
    if (i == maxCount) break; }}Copy the code

4. Create from zero and useStreamControllerWay. The development of this way to achieve the broadcast effect, the end of the extension.

// The simulation injects data into the stream every second
Stream<int> createStream(int maxCount) {
  var controller = new StreamController<int> ();int i = 0;
  while (true) {
    controller.add(i);
    if (i == maxCount) {
      controller.close();
      break; }}return controller.stream;
}
Copy the code

StreamThere are two types:

  • Single mode:controller.streamOnly one listener can be set at a time
  • Broadcast mode:controller.broadcast().streamMultiple listeners can be set at the same time

> Subscribe to listenStream

The Stream layer provides the listen() method:

/ / drop in the SDK
StreamSubscription<T> listen(voidonData(T event)? , {Function? onError, voidonDone()? .bool? cancelOnError});
Copy the code

In development, common usage is as follows: Subscription listening

Stream<int> stream = createStream(15); // Generate content streams with 1 to 15 data

StreamSubscription<int> subscription;

void onData(int value){
  // For specific business processes, such as printing, print 1 to 15 in order
  print(value);
}
// Start listening
subscription = stream.listen(onData);
Copy the code

Stop listening

subscription.pause();
Copy the code

Restore to monitor

if(subscription.isPaused){
  subscription.resume();
}
Copy the code

Cancel to monitor

subscription.cancel();
Copy the code

> introduction afterStreamFinally, let’s take a lookStreamHow is the transformation layer implemented

The following code example shows two ways to multiply a Stream of type int by 2 and convert it to a Stream of type String

1. Use可迭代Built-in function

Stream<String> transformStream1(Stream<int> stream) {
  // Method 1:
  // return stream.expand<String>((element) => [(element * 2).toString()]);
  
  // Method 2:
  Future source = stream.map((x) => (x * 2).toString()).toList();
  return new Stream<String>.fromFuture(source);
}
Copy the code

2. UsetransformerThe way of

Stream<String> transformStream2(Stream<int> stream) {
  final transFormer = StreamTransformer<int.String>.fromHandlers(
    handleData: (value, sink) {
      sink.add((value * 2).toString()); });return stream.transform<String>(transFormer);
}
Copy the code

The development ofStreamCommon application scenarios

  • Can be used to implementBroadcast Event notification , Flutter uses a Stream for message notification
  • Can be used to implementPolling for specific services , Flutter: Stream implements timed polling
  • In combination withFuture,CompleterImplement the task queue,The Flutter custom task queue