简体   繁体   中英

Is it possible to yield to an outer scope in Dart?

Is it possible to somehow yield to an outer scope? Is there a more idiomatic approach that achieves the same intended result?

Stream<T> fetch() async* {
  bool sentLiveValue = false;

  Future<T> cached = cache.fetchValue();
  cached.then((value) {
    if (!sentLiveValue)
      yield value; // Here, I want to yield to the outer scope.
  });

  await for (T value in liveValueSource.fetch()) {
    yield value;
    sentLiveValue = true;
    cache.update(value);
  }
}

If you're wondering about context, I'm implementing a data architecture with classes that can fetch data. The simplified code above should return a stream that first contains a cached value and then contains values from a live source.

Note that if the cache is slower than the live data source (which is possible if the cache doesn't contain a value yet), the live data should be used first. So await ing the cache value is not an option.

One solution is to use a StreamController , but beware: making your own streams is hazardous - you should handle listen, pause, resume and cancel.

A partial implementation is:

Stream<T> fetch<T>() {
  var sentLiveValue = false;
  var controller = StreamController<T>(
    onListen: () {},
    onPause: () {},
    onResume: () {},
    onCancel: () {},
  );

  cache.fetchValue().then((v) {
    if (!sentLiveValue) {
      controller.add(v);
    }
  });

  liveValueSource.fetch().listen(
    (t) {
      sentLiveValue = true;
      cache.update(t);
      controller.add(t);
    },
    onDone: () => controller.close(),
    onError: (e, st) => controller.addError(e, st),
  );

  return controller.stream;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM