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

Dart/Flutter中await未等待Future执行完成就运行后续代码问题

问题原因

该现象本质是loadHabitsSortOrder()未等内部排序字段赋值逻辑执行完毕就提前返回,外层await loadHabitsSortOrder()提前结束等待,导致sortHabitsList()先被触发。
最常见的诱因是调用的fold是异步版本(如dartz的foldAsync、自定义返回Future的扩展方法),但调用时未加await:执行response.fold()时,方法仅将两个分支的回调加入微任务队列排队,自身立即返回,loadHabitsSortOrder同步执行到函数末尾就返回完成状态,外层await结束后直接执行sortHabitsList();等sort的全量同步逻辑执行完毕,事件循环才会处理微任务队列中的fold回调,完全匹配断点观测到的执行顺序。
小概率场景是miscRepository.getItem()内部拿到结果后,同步触发了排序相关的监听回调(如ChangeNotifier的notifyListeners、事件总线事件发射),直接触发sort逻辑,打断了当前赋值流程。

修复方案
  • 检查response.fold()的返回值类型,如果返回值为Future,在调用前加await,确保fold内的分支逻辑(错误弹窗、排序字段赋值)全部执行完成后,loadHabitsSortOrder才标记为执行完成,修改后代码如下:
Future<void> loadHabitsSortOrder() async {
    Either<Failure, dynamic> response =
        await miscRepository.getItem(AppStrings.sortOrderMapKey);

    // 增加await等待fold内部逻辑执行完毕
    await response.fold(
      (failure) => DialogHelper.showErrorDialog(failure),
      (sortingOrder) {
        if (sortingOrder != null) {
          currentSortOrder = sortingOrder['sortOrder'];
          sortedHabitIds = sortingOrder['sortedHabitIds'];
        }
      },
    );
  }
  • 若加await后顺序仍异常,排查miscRepository.getItem()内部实现,禁止在返回结果前同步触发排序相关的更新通知,这类通知可移到方法末尾,或通过WidgetsBinding.instance.addPostFrameCallback延迟到当前同步流程执行完成后再触发,避免打断异步执行链路。
  • 调试阶段可在fold两个回调入口、sortHabitsList方法首行加打印日志,直观观测实际调用顺序,快速定位链路问题。

内容的提问来源于stack exchange,提问作者Haaris Ahamed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:39:18