Stream何时开始将值发布给侦听器?

时间:2019-06-21 11:12:25

标签: dart stream reactive-programming

在阅读了很多有关dart中Streams和StreamControllers的文档后,我尝试构建一个小示例,并对结果感到惊讶。我阅读的所有文档都指出,注册侦听器后,流就开始发射数据。但这不会显示任何打印数据:

class Order
{
  String type;
  Order(this.type);
}

class Pizza
{

}



void main()
{
  Order order = Order("pzza");

  final StreamController sc = StreamController();

  sc.sink.add(order);
  sc.sink.add(order);
  sc.sink.add(new Order("pizza"));

  Stream st = sc.stream.map((order) {
    return order.type;
  })
  .map((orderType) {
    if(orderType == "pizza")
      return Pizza();
    else
      throw ("dude!, I don't know how to do that");
  });

  var sus = st.listen((pizza)
    {
      print("We did a pizza");
    },
    onError: (error)
    {
      print(error);
    });

    sus.cancel();

    sc.sink.add(new Order("pizza2"));
}

我期待着这个输出:

dude!, I don't know how to do that
dude!, I don't know how to do that
We did a pizza

在创建流并添加数据时,是否计划在下一个应用程序步骤中发出所有“下沉”的数据?

干杯。

1 个答案:

答案 0 :(得分:0)

您是正确的,该文档指出您在流上侦听以使其开始生成事件。但是,流是异步的,因此当您调用listen()方法时,您正在注册以在将来的某个时刻接收来自流的事件。然后,Dart将继续运行其余主要功能。致电listen()后,您立即致电cancel()取消订阅,这就是为什么没有打印任何内容的原因。

如果您删除或注释掉取消并再次运行它,您将看到预期的输出。

对代码进行略微修改的版本有望突出显示事件的运行:

class Order {
  String type;
  Order(this.type);
}

class Pizza {}

void main() {
  print("Main starts");

  Order order = Order("pzza");

  final StreamController sc = StreamController();

  sc.sink.add(order);
  sc.sink.add(order);
  sc.sink.add(new Order("pizza"));

  Stream st = sc.stream.map((order) {
    return order.type;
  }).map((orderType) {
    if (orderType == "pizza")
      return Pizza();
    else
      throw ("dude!, I don't know how to do that");
  });

  var sus = st.listen((pizza) {
    print("We did a pizza");
  }, onError: (error) {
    print(error);
  });

  // sus.cancel();

  sc.sink.add(new Order("pizza2"));

  print("Main ends");
}

运行此命令将产生输出:

Main starts
Main ends
dude!, I don't know how to do that
dude!, I don't know how to do that
We did a pizza
dude!, I don't know how to do that