You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter BLoC中Dio请求超时后事件重复触发问题求助

Flutter BLoC请求超时后事件重复触发循环问题

问题详情

调用需同网访问的私有API时,用移动数据测试会触发请求超时。在BLoC中调用该接口后,通过BLoCBuilder渲染UI时出现以下异常流程:

  1. 先返回DoctorsLoadingState
  2. 接着返回DoctorErrorState
  3. 随后LoadAllSpecialities事件被重复触发,进入多次失败的循环

期望实现:触发一次ErrorState后停止监听该事件,尝试使用droppable()转换器但未生效。

相关代码

BLoC事件处理方法

void _loadAllSpecialities(
      LoadAllSpecialities event, Emitter<DoctorsState> emit) async {
    emit(
      const DoctorsLoadingState(),
    );
    emit(const DoctorsLoadingState());
    final result = await doctorService.getAllSpeciality(event.jwtToken);
    print(result.toString());
    //无错误且数据加载完成
    if (result.item1 == null) {
      final speicailities = result.item2;

      emit(DoctorsSpecialitiesLoaded(specialities: speicailities));
    } else {
      //存在错误(error不为null)
      emit(DoctorErrorState(result.item1!));
    }
  }

DoctorService类

class DoctorService {
  final List<DoctorSpeciality> specialities = [];
  final options = Options(
    responseType: ResponseType.json,
    receiveTimeout: 2000,
    sendTimeout: 2000,
  );
  final _dio = Dio();
  Future<Tuple<String?, List<DoctorSpeciality>>> getAllSpeciality(
      String jwtToken) async {
    specialities.clear();
    var tuple = Tuple<String?, List<DoctorSpeciality>>(null, []);

    try {
      final response = await _dio.get<List>(ApiVars.specialitiesEndPoint,
          options:
              options.copyWith(headers: {"Authorization": "Bearer $jwtToken"}));
      if (response.statusCode == 200) {
        //无数据返回
        if (response.data == null) {
          //设置错误信息
          tuple.setNewValues('无数据加载', []);
          log(tuple.item1 ?? '');
          return tuple;
        }
        //有数据则映射为DoctorSpeciality列表
        response.data?.forEach((element) {
          specialities.add(DoctorSpeciality.fromJson(element));
        });
        tuple.setNewValues(null, specialities);
        return tuple;
      } else {
        tuple.setNewValues('请求错误,状态码:${response.statusCode}', []);
        log(tuple.item1 ?? '');
        return tuple;
      }
    } on DioError catch (error) {
      tuple.setNewValues("服务异常:${error.message}", []);
      log(tuple.item1 ?? '');
      return tuple;
    }
  }
}

已尝试的方案

使用droppable()转换器,但未解决循环问题:

on<LoadAllSpecialities>(_loadAllSpecialities, transformer: droppable());

内容的提问来源于stack exchange,提问作者Ahmed Ashraf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:10:44