description

# Stream<T>.periodic constructor Null safety

Stream<T>.periodic(

1. Duration period,
2. [T computation(
   1. int computationCount
   )]

)

Creates a stream that repeatedly emits events at `period` intervals.

The event values are computed by invoking `computation`. The argument to this callback is an integer that starts with 0 and is incremented for every event.

The `period` must a non-negative Duration.

If `computation` is omitted the event values will all be `null`.

The `computation` must not be omitted if the event type `T` does not allow `null` as a value.

## Implementation

    factory Stream.periodic(Duration period,
        [T computation(int computationCount)?]) {
      if (computation == null && !typeAcceptsNull<T>()) {
        throw ArgumentError.value(null, "computation",
            "Must not be omitted when the event type is non-nullable");
      }
      var controller = _SyncStreamController<T>(null, null, null, null);
      // Counts the time that the Stream was running (and not paused).
      Stopwatch watch = new Stopwatch();
      controller.onListen = () {
        int computationCount = 0;
        void sendEvent(_) {
          watch.reset();
          if (computation != null) {
            T event;
            try {
              event = computation(computationCount++);
            } catch (e, s) {
              controller.addError(e, s);
              return;
            }
            controller.add(event);
          } else {
            controller.add(null as T); // We have checked that null is T.
          }
        }

        Timer timer = Timer.periodic(period, sendEvent);
        controller
          ..onCancel = () {
            timer.cancel();
            return Future._nullFuture;
          }
          ..onPause = () {
            watch.stop();
            timer.cancel();
          }
          ..onResume = () {
            Duration elapsed = watch.elapsed;
            watch.start();
            timer = new Timer(period - elapsed, () {
              timer = Timer.periodic(period, sendEvent);
              sendEvent(null);
            });
          };
      };
      return controller.stream;
    }