merge method

Effect<Action> merge(
  1. Effect<Action> other
)

Merges other with this, becoming a single Effect that emits every action from both effects.

The order of the actions depend on the order internal computations are made, so there is no pre condition that determines whether the actions of other or this will come first.

Implementation

Effect<Action> merge(Effect<Action> other) {
  return Effect(() {
    final controller = StreamController<Action>();
    final id = _cancellableEffects[_cancellableId];
    final otherId = _cancellableEffects[other._cancellableId];

    CancellableSubscription? subscription;
    CancellableSubscription? otherSubscription;

    subscription = CancellableSubscription(builder().listen((value) {
      if (!controller.isClosed) {
        controller.add(value);
      } else {
        subscription?.cancel();
      }
    }));

    otherSubscription =
        CancellableSubscription(other.builder().listen((value) {
      if (!controller.isClosed) {
        controller.add(value);
      } else {
        otherSubscription?.cancel();
      }
    }));
    var thisDone = false;
    var otherDone = false;

    subscription.onDone(() {
      thisDone = true;
      if (otherDone) {
        controller.close();
      }
    });

    otherSubscription.onDone(() {
      otherDone = true;
      if (thisDone) {
        controller.close();
      }
    });

    if (id != null) {
      _effectSubscriptions[id] = subscription;
    }

    if (otherId != null) {
      _effectSubscriptions[otherId] = otherSubscription;
    }

    return controller.stream;
  });
}