Dart中将Iterable转换为Stream的最佳/最短方法是什么?

时间:2015-03-31 19:12:21

标签: dart dart-async

我有一个Iterable,我想将它转换为Stream。什么是最有效/最短的代码量?

例如:

Future convert(thing) {
  return someAsyncOperation(thing);
}

Stream doStuff(Iterable things) {
  return things
    .map((t) async => await convert(t)) // this isn't exactly what I want
                                        // because this returns the Future
                                        // and not the value
    .where((value) => value != null)
    .toStream(); // this doesn't exist...
}

注意:iterable.toStream()不存在,但我想要这样的东西。 :)

3 个答案:

答案 0 :(得分:6)

这是一个简单的例子:

var data = [1,2,3,4,5]; // some sample data
var stream = new Stream.fromIterable(data);

使用您的代码:

Future convert(thing) {
  return someAsyncOperation(thing);
}

Stream doStuff(Iterable things) {
  return new Stream.fromIterable(things
    .map((t) async => await convert(t))
    .where((value) => value != null));
}

答案 1 :(得分:3)

如果您使用的是Dart SDK 1.9或更新版本,您可以使用async *轻松创建流

import 'dart:async';

Future convert(thing) {
  return new Future.value(thing);
}

Stream doStuff(Iterable things) async* {
  for (var t in things) {
    var r = await convert(t);

    if (r != null) {
      yield r;
    }
  }
}

void main() {
  doStuff([1, 2, 3, null, 4, 5]).listen(print);
}

也许它更容易阅读,因为它没有大括号和#34;特殊"方法,但这是一个品味问题。

答案 2 :(得分:1)

如果要按顺序处理iterable中的每个项目,可以使用Stream.asyncMap

Future convert(thing) {
  return waitForIt(thing);   // async operation
}

f() {
  var data = [1,2,3,4,5];
  new Stream.fromIterable(data)
    .asyncMap(convert)
    .where((value) => value != null))
}