Stream <E> asyncExpand <E>(Func <T, Stream <E> > convert) { _StreamControllerBase <E> controller = null; StreamSubscription <T> subscription = null; void onListen() { D.assert(controller is _StreamController <E> || controller is _BroadcastStreamController <E>); subscription = listen((T evt) => { Stream <E> newStream; try { newStream = convert(evt); } catch (Exception e) { controller.addError(e, e.StackTrace); return; } if (newStream != null) { subscription.pause(); controller.addStream(newStream).whenComplete(subscription.resume); } }, onError: controller._addError, // Avoid Zone error replacement. onDone: () => controller.close()); } if (isBroadcast) { controller = (_StreamControllerBase <E>) StreamController <E> .broadcast( onListen : () => onListen(), onCancel : () => { subscription.cancel(); }, sync : true); } else { controller = (_StreamControllerBase <E>) StreamController <E> .create( onListen : () => onListen(), onPause : () => { subscription.pause(); }, onResume : () => { subscription.resume(); }, onCancel : () => subscription.cancel(), sync : true); } return(controller.stream); }
public Stream <E> asyncMap <E>(Func <T, FutureOr> convert) { _StreamControllerBase <E> controller = null; StreamSubscription <T> subscription = null; void onListen() { var add = new Action <E>(controller.add); D.assert(controller is _StreamController <E> || controller is _BroadcastStreamController <E>); var addError = new Action <object, string>(controller._addError); subscription = listen((T evt) => { FutureOr newValue; try { newValue = convert(evt); } catch (Exception e) { controller.addError(e, e.StackTrace); return; } if (newValue.f is Future <E> newFuture) { // siyao: this if different from dart subscription.pause(); newFuture .then(d => add((E)d), onError: (e) => { addError(e, e.StackTrace); return(FutureOr.nil); }) .whenComplete(subscription.resume); } else { // Siyao: This works as if this is csharpt controller.add((E)newValue.v); } }, onError: addError, onDone: () => controller.close()); } if (isBroadcast) { controller = (_StreamControllerBase <E>) StreamController <E> .broadcast( onListen : () => onListen(), onCancel : () => { subscription.cancel(); }, sync : true); } else { controller = (_StreamControllerBase <E>) StreamController <E> .create( onListen : onListen, onPause : () => { subscription.pause(); }, onResume : () => { subscription.resume(); }, onCancel : () => subscription.cancel(), sync : true); } return(controller.stream); }