问题描述
我的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里面,我将value递增到我的状态; 但是我在增量之前和之后打印,并且状态是相同的值; 测试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());
},```
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
lambda中的代码完全顺序执行时,没有Future.delayed(Duration.zero)
(您可能已经使用onPressed
)。 add
方法调用mapEventToState
,这是一个异步方法(实际上是生成器)。当Dart遇到这样的方法时,它将安排它以供以后执行并前进到下一条指令。因此,您将两次看到0
。
当您添加await
之类的Future.delayed
呼叫时,这种情况会改变。然后Dart将停止并查看它还能运行什么。在这种情况下,mapEventToState
。它会运行那个,然后继续处理onPressed
lambda的其余部分。这就是为什么您看到1
和期待的Future.delayed
的原因。