繁体   English   中英

更新示例计数器中的非即时 state - BloC Flutter

[英]Update of the not immediate state in Example Counter - BloC Flutter

我的 pubspec.yml:

  bloc: ^4.0.0
  flutter_bloc: ^4.0.0
  equatable: ^1.2.5

我创建了我的 CounterBloc:

class CounterBloc extends Bloc<CounterEvent, int> {
  @override
  int get initialState => 0;

  @override
  Stream<int> mapEventToState(event) async* {
    if (event.status == EventStatus.INCREMENT) {
      yield state + event.value;
    } else if (event.status == EventStatus.DECREMENT) {
      yield state - event.value;
    }
  }
}
enum EventStatus { INCREMENT, DECREMENT }

class CounterEvent {
  final int value;
  final EventStatus status;

  const CounterEvent({this.value, this.status});
}
void main() => runApp(CounterApp());

class CounterApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'BLoC Demo',
      home: BlocProvider<CounterBloc>(
        create: (context) => CounterBloc(),
        lazy: false,
        child: TestBlocWidget(),
      ),
    );
  }
}
class TestBlocWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counterBloc = BlocProvider.of<CounterBloc>(context);
    return Scaffold(
      body: Center(
        child: BlocBuilder<CounterBloc, int>(
          builder: (ctx, state) {
            return Text(
              'count: $state',
              style: TextStyle(fontSize: 28),
            );
          },
        ),
      ),
      floatingActionButton: Align(
        alignment: Alignment.bottomRight,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            FloatingActionButton(
              onPressed: () async {
                print("test 0 = " + counterBloc.state.toString());
                counterBloc.add(CounterEvent(value: 1, status: EventStatus.INCREMENT));
                print("test 1 = " + counterBloc.state.toString());
              },
              child: Icon(Icons.add_circle),
            ),
            FloatingActionButton(
              onPressed: () {
                print("test 2 = " + counterBloc.state.toString());
                counterBloc
                    .add(CounterEvent(value: 1, status: EventStatus.DECREMENT));
                print("test 3 = " + counterBloc.state.toString());
              },
              child: Icon(Icons.remove_circle),
            ),
          ],
        ),
      ),
    );
  }
}

那么我的问题是:

在 FloatingActionButton 内部,我将值增加到我的 state; 但是我在增量之前和增量之后打印,而 state 是相同的值; 测试 0 = 0; 测试 1 = 0; 为什么? 在屏幕上反映我的值,但不会立即在我的 FloatingActionButton 里面打印;

在我测试了这个之后:

            FloatingActionButton(
              onPressed: () async {
                print("test 0 = " + counterBloc.state.toString());
                counterBloc
                    .add(CounterEvent(value: 1, status: EventStatus.INCREMENT));
                await Future.delayed(Duration(milliseconds: 0));
                print("test 1 = " + counterBloc.state.toString());
              },
              child: Icon(Icons.add_circle),
            ),
    ```

Note: I put "await Future.delayed", after my CounterBloc, with value 0 in my FloatingActionButton;
Works;
test 0 = 0;
test 1 = 1;

这是因为调度程序的工作方式。 Dart 代码在单个事件循环上执行。 执行指令的顺序受await的影响。

如果没有Future.delayed (顺便说一句,您可以使用Future.delayed(Duration.zero) ),当onPressed lambda 中的代码完全按顺序执行时。 add方法调用mapEventToState ,这是一个异步方法(实际上是生成器)。 当 Dart 遇到这样的方法时,它将安排它稍后执行并前进到下一条指令。 因此你会看到0两次。

当您添加像Future.delayed这样的await调用时,这会发生变化。 然后 Dart 将停止并查看它还能运行什么。 在这种情况下是mapEventToState 它将运行那个,之后它将继续onPressed lambda 的剩余部分。这就是为什么您看到1和等待的Future.delayed

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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