更新示例计数器中的非立即状态 - BloC Flutter
Posted
技术标签:
【中文标题】更新示例计数器中的非立即状态 - BloC Flutter【英文标题】:Update of the not immediate state in Example Counter - BloC Flutter 【发布时间】:2021-01-08 01:25:15 【问题描述】:我的 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 内部,我将值递增到我的状态; 但是我在增量之前和之后打印并且状态是相同的值; 测试 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;
【问题讨论】:
【参考方案1】:这是因为调度程序的工作方式。 Dart 代码在单个事件循环上执行。指令执行顺序受await
影响。
当onPressed
lambda 中的代码完全按顺序执行时,如果没有Future.delayed
(顺便说一下,您可以使用Future.delayed(Duration.zero)
)。 add
方法调用 mapEventToState
,这是一个异步方法(实际上是生成器)。当 Dart 遇到这样的方法时,它会安排它稍后执行并进入下一条指令。因此你会看到0
两次。
当您添加await
调用(如Future.delayed
)时,这种情况会发生变化。 Dart 然后会停下来看看它还能运行什么。在这种情况下,mapEventToState
。它将运行那个,之后它将继续使用 onPressed
lambda 的其余部分。这就是为什么您会看到 1
和期待已久的 Future.delayed
。
【讨论】:
以上是关于更新示例计数器中的非立即状态 - BloC Flutter的主要内容,如果未能解决你的问题,请参考以下文章
Flutter BLoC:在父 Widget 更新时维护子状态
我正在借助 bloc(cubit)创建异步计数器应用程序,每次计数器返回 0 时我都会发出加载状态
我正在使用 BLOC 制作一个简单的计数器应用程序,但是当我增加/减少计数器时,我的计数器没有更新?我使用 BlocBuilder 构建 UI