简体   繁体   English

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

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

My pubspec.yml:我的 pubspec.yml:

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

I created my CounterBloc:我创建了我的 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),
            ),
          ],
        ),
      ),
    );
  }
}

Then my question is:那么我的问题是:

Inside FloatingActionButton, I increment value to my state;在 FloatingActionButton 内部,我将值增加到我的 state; But I print before increment and after increment and the state is the same value;但是我在增量之前和增量之后打印,而 state 是相同的值; test 0 = 0;测试 0 = 0; test 1 = 0;测试 1 = 0; Why?为什么? In the screen reflect my value, but not immediately in my prints inside FloatingActionButton;在屏幕上反映我的值,但不会立即在我的 FloatingActionButton 里面打印;

After I tested this:在我测试了这个之后:

            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;

That is because of how the scheduler works.这是因为调度程序的工作方式。 Dart code is executed on a single event loop. Dart 代码在单个事件循环上执行。 The order in which instructions are executed is influenced by await .执行指令的顺序受await的影响。

Without the Future.delayed (you could have used Future.delayed(Duration.zero) by the way) when code in the onPressed lambda is executed entirely sequentially.如果没有Future.delayed (顺便说一句,您可以使用Future.delayed(Duration.zero) ),当onPressed lambda 中的代码完全按顺序执行时。 The add method calls mapEventToState which is an async method (generator really).add方法调用mapEventToState ,这是一个异步方法(实际上是生成器)。 When Dart encounters such a method it will schedule it for later execution and progress to the next instruction.当 Dart 遇到这样的方法时,它将安排它稍后执行并前进到下一条指令。 Therefor you will see 0 twice.因此你会看到0两次。

This changes when you add an await call like your Future.delayed .当您添加像Future.delayed这样的await调用时,这会发生变化。 Dart will then stop and see what else it can run.然后 Dart 将停止并查看它还能运行什么。 In this case the mapEventToState .在这种情况下是mapEventToState It will run that one and after it will continue on with the remainder of the onPressed lambda. That is why you see 1 with the awaited Future.delayed .它将运行那个,之后它将继续onPressed lambda 的剩余部分。这就是为什么您看到1和等待的Future.delayed

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

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