description

# Stream<T>.fromIterable constructor

Stream<T>.fromIterable(

1. Iterable<T> elements

)

Creates a stream that gets its data from `elements`.

The iterable is iterated when the stream receives a listener, and stops iterating if the listener cancels the subscription, or if the Iterator.moveNext method returns `false` or throws. Iteration is suspended while the stream subscription is paused.

If calling Iterator.moveNext on `elements.iterator` throws, the stream emits that error and then it closes. If reading Iterator.current on `elements.iterator` throws, the stream emits that error, but keeps iterating.

Can be listened to more than once. Each listener iterates `elements` independently.

Example:

    final numbers = [1, 2, 3, 5, 6, 7];
    final stream = Stream.fromIterable(numbers);

## Implementation

    factory Stream.fromIterable(Iterable<T> elements) =>
        Stream<T>.multi((controller) {
          Iterator<T> iterator;
          try {
            iterator = elements.iterator;
          } catch (e, s) {
            var error = _interceptCaughtError(e, s);
            controller.addError(error.error, error.stackTrace);
            controller.close();
            return;
          }
          var zone = Zone.current;
          var isScheduled = true;

          void next() {
            if (!controller.hasListener || controller.isPaused) {
              // Cancelled or paused since scheduled.
              isScheduled = false;
              return;
            }
            bool hasNext;
            try {
              hasNext = iterator.moveNext();
            } catch (e, s) {
              var error = _interceptCaughtError(e, s);
              controller.addErrorSync(error.error, error.stackTrace);
              controller.closeSync();
              return;
            }
            if (hasNext) {
              try {
                controller.addSync(iterator.current);
              } catch (e, s) {
                var error = _interceptCaughtError(e, s);
                controller.addErrorSync(error.error, error.stackTrace);
              }
              if (controller.hasListener && !controller.isPaused) {
                zone.scheduleMicrotask(next);
              } else {
                isScheduled = false;
              }
            } else {
              controller.closeSync();
            }
          }

          controller.onResume = () {
            if (!isScheduled) {
              isScheduled = true;
              zone.scheduleMicrotask(next);
            }
          };

          zone.scheduleMicrotask(next);
        });