Dart中.fold方法内await后调用emit触发报错的问题及解决
解决Dart中fold方法内执行await异步函数后emit报错的问题
问题描述
在Dart的.fold方法中执行带await的异步函数后,触发报错:
emit was called after an event handler completed normally.
代码示例:
_failureOrProperty.fold( (failure) async => emit(state.copyWith( status: () => DataTransStatus.failure, (data) async { final List<int>? taskTypeCnts = await getTasksCount(_calledId!); // final List<int>? taskTypeCnts=[1,1]; emit(state.copyWith( status: () => DataTransStatus.success, noOfMandatory: () => taskTypeCnts?[0], noOfOptional: () => taskTypeCnts?[1] )); }
使用注释中的同步代码时一切正常,但调用await getTasksCount()就会触发报错。
问题原因
.fold方法本身是同步设计,当给它传递带async的异步回调时,fold不会等待异步操作完成就会结束执行。如果这段代码是在Bloc的事件处理函数中,当await挂起时,事件处理会被标记为已完成,后续异步操作结束后调用emit就会触发上述报错。
解决方案
方案1:改用显式类型判断
直接判断_failureOrProperty的类型,确保异步操作和emit都在事件处理上下文内执行:
// 替换fold写法,直接判断结果类型 if (_failureOrProperty is Left) { emit(state.copyWith( status: () => DataTransStatus.failure, )); } else { final data = (_failureOrProperty as Right).value; final List<int>? taskTypeCnts = await getTasksCount(_calledId!); emit(state.copyWith( status: () => DataTransStatus.success, noOfMandatory: () => taskTypeCnts?[0], noOfOptional: () => taskTypeCnts?[1] )); }
方案2:保留fold并等待异步完成
如果仍想使用fold,需确保事件处理函数本身为async,并等待fold返回的Future完成:
await _failureOrProperty.fold( (failure) async { emit(state.copyWith( status: () => DataTransStatus.failure, )); }, (data) async { final List<int>? taskTypeCnts = await getTasksCount(_calledId!); emit(state.copyWith( status: () => DataTransStatus.success, noOfMandatory: () => taskTypeCnts?[0], noOfOptional: () => taskTypeCnts?[1] )); }, );
两种方案都能保证emit在事件处理上下文未结束时执行,避免报错。
内容的提问来源于stack exchange,提问作者w461
相关产品推荐
相关产品推荐

