Flutter StreamBuilder在初始化时称为两次 [英] Flutter StreamBuilder Called Twice When Initialized

查看:541
本文介绍了Flutter StreamBuilder在初始化时称为两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

StreamBuilder是否总是被调用两次?一次用于初始数据,然后一次用于输入流?

Is StreamBuilder always called twice? Once for initial data and then once for the input stream?

初始化以下StreamBuilder表示,两次调用了build方法。第二个调用是在第一个调用之后的0.4秒。

Initializing the following StreamBuilder shows that the build method is called twice. The second call is 0.4 seconds after the first one.

流:内部版本1566239814897

Stream: Build 1566239814897

流:内部版本1566239815284

Stream: Build 1566239815284

import 'dart:async';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:nocd/utils/bloc_provider.dart';

void main() =>
    runApp(BlocProvider<MyAppBloc>(bloc: MyAppBloc(), child: MyApp()));

class MyAppBloc extends BlocBase {
  String _page = window.defaultRouteName ?? "";

  /// Stream for [getPage].
  StreamController<String> pageController = StreamController<String>();

  /// Observable navigation route value.
  Stream get getPage => pageController.stream;

  MyAppBloc() {}

  @override
  void dispose() {
    pageController.close();
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final MyAppBloc myAppBloc = BlocProvider.of<MyAppBloc>(context);
    return StreamBuilder(
      stream: myAppBloc.getPage,
      initialData: "Build",
      builder: (context, snapshot) {
        print("Stream: " +
            snapshot.data +
            DateTime.now().millisecondsSinceEpoch.toString());
        return Container();
      },
    );
  }
}

为什么StreamBuilder被调用两次?

Why is the StreamBuilder called twice?

推荐答案

StreamBuilder在初始化时进行两次构建调用,一次用于初始数据,第二次用于流数据。

StreamBuilder makes two build calls when initialized, once for the initial data and a second time for the stream data.

流不保证它们将立即发送数据,因此需要初始数据值。将 null 传递给 initialData 会引发InvalidArgument异常。

Streams do not guarantee that they will send data right away so an initial data value is required. Passing null to initialData throws an InvalidArgument exception.

即使传递的流为null,StreamBuilders也会始终生成两次。

StreamBuilders will always build twice even when the stream passed is null.

更新:

关于为何StreamBuilders甚至生成多次的详细技术说明在以下Flutter问题线程中可以找到提供 initalData 时: https://github.com/flutter/flutter/issues/16465

A detailed technical explanation of why StreamBuilders build multiple times even when an initalData is provided can be found in this Flutter issue thread: https://github.com/flutter/flutter/issues/16465


广播流具有初始状态。添加数据时您已订阅或错过了数据。在异步单订阅流中,添加的任何侦听调用都不会被调用,直到下一个微任务或下一个事件循环(不记得了,可能取决于)为止,但是无论如何都无法从中获取数据。当前帧上的流。 -jonahwilliams

It's not possible for a broadcast stream to have an initial state. Either you were subscribed when the data was added or you missed it. In an async single-subscription stream, any listen calls added won't be invoked until either the next microtask or next event loop (can't remember, may depend), but at any rate there is no way to get the data out the stream on the current frame. - jonahwilliams

这篇关于Flutter StreamBuilder在初始化时称为两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆