当我运行下面的代码时,我希望看到:
流1说:true
流1说:false
流2说:正确
因为这是将数据添加到StreamController的顺序。
但是我看到:
流1说:true
流2说:正确
流1说:false

import 'dart:async';
void main() {
  StreamController<bool> streamController1 = StreamController();
  StreamController<bool> streamController2 = StreamController();


  void _handleStream1(bool thing){
    print("Stream 1 says: " + thing.toString());
  }

  void _handleStream2(bool thing){
    print("Stream 2 says: " + thing.toString());
  }

  streamController1.stream.listen(_handleStream1);
  streamController2.stream.listen(_handleStream2);

  streamController1.sink.add(true);
  streamController1.sink.add(false);

  streamController2.sink.add(true);
}

  • 为什么会这样?
  • 如何确定执行顺序?

  • 我发现如果将数据以dart的相同隔离方式添加到流中,则侦听器将被称为FIFO样式,但我可能会缺少一些基本知识!

    最佳答案

    因此,这最终成为Dart代码库内部的一次“有趣”冒险。简而言之,我认为真正发生的事情是:

  • 您正在向两个接收器添加元素。
  • 将第一个项目添加到Sink(来自StreamController)时,Dart将在后台调度一个微任务。但这只会在尚未为此Sink安排任务的情况下发生。
  • 第一个微任务(来自streamController1)正在运行,并将处理一个值。执行完此事件后,它将检查是否还有更多事件要处理。如果是这样,它将安排一个新的微任务。
  • 接下来的微任务将由streamController2处理,我们正在处理此值。由于此StreamController没有更多值,因此我们不安排其他微任务。
  • 我们将处理最后一个微任务(从步骤3派生的那个)以处理streamController1中的最后一个值。

  • 我没有找到任何表明这种设计原因的迹象,但是如果我有一个猜测,我认为已经做到了,这样您就不会遇到单个StreamController优先而不为其他StreamController实例腾出空间的情况。 。
    这是可以的,因为我们不应期望另一个已执行事件在StreamController的各个实例之间按任何特定顺序排列。如果顺序很重要,则应将代码放在第一个listen内,或者在此生成新事件(如果它取决于第一个处理程序的执行)。
    注意:我无法轻松解释我是如何发现细节的,因为该体系结构似乎受意大利面条怪兽的启发(我很确定一切背后都有逻辑)。但是您可以在以下链接中搜索:
  • https://github.com/dart-lang/sdk/blob/2.10.1/sdk/lib/async/stream_controller.dart
  • https://github.com/dart-lang/sdk/blob/2.10.1/sdk/lib/async/stream_impl.dart
  • 10-08 18:04