簡體   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