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

Dart异步缓存代码触发TimeoutException: Future not completed问题咨询

代码核心问题分析
  • 第一个严重问题:异常场景下未清理pendingFutures的key
    你当前的pendingFutures.remove逻辑只写在查询成功的执行路径下,一旦connection.query抛出TimeoutException或者其他异常,代码会直接跳转至catch块,永远不会执行remove操作。
    Dart的Future会永久缓存执行结果(包括异常),后续同一个sql的请求会命中if(pendingFutures.containsKey)分支,await这个已经抛出过超时异常的Future,会直接重复抛出之前的TimeoutException,这就是你偶发报错的核心诱因。而且此时await直接抛出异常,你后面的print("This Line is already do not prints")自然不会执行,完全符合你遇到的现象。
  • 第二个问题:存在并发竞争的隐患
    当多个请求同时查询同一个sql时,可能出现:请求A刚执行完remove操作删除key,请求B刚完成containsKey判断为true,接下来await pendingFutures[sqlQuery.hashCode]时取到的是null,虽然Dart里await null不会报错,但不符合你的业务设计预期。
  • 第三个问题:不必要的await操作
    pendingFutures.remove是Map的同步方法,返回的是被删除的元素而非Future,前面加await属于多余写法,虽然不会直接导致报错,但属于不规范代码。
Future默认超时机制说明

Dart标准库的原生Future没有默认超时机制,你遇到的超时是connection.query方法自身实现的超时逻辑,和你传入的timeoutInSeconds: 3600参数对应,超时后主动抛出TimeoutException,不是Dart Future的默认行为。

修复代码示例
Future<void> addResultToCache(String sqlQuery) async {
  final queryKey = sqlQuery.hashCode;
  try {
    if(pendingFutures.containsKey(queryKey)) {
      print('This query is already running');
      final runningFuture = pendingFutures[queryKey];
      // 额外判空避免并发删除导致的空值问题
      if (runningFuture != null) {
        await runningFuture;
      }
      print("This Line will now print normally"); 
    } else {
      final queryFuture = connection.query(sqlQuery, timeoutInSeconds: 3600);
      pendingFutures[queryKey] = queryFuture;
      try {
        var queryResult = await queryFuture;
        var queryObj = RequestCacheStruct(queryKey, DateTime.now(), queryResult!);
        requestsCacheList.add(queryObj);
        print('Query was added to cache');
      } finally {
        // 不管查询成功还是失败,最终都清理key
        pendingFutures.remove(queryKey);
      }
    }
  } on TimeoutException catch(e) {
    print('TimeoutException: ${e.message}' );
  }
}

内容的提问来源于stack exchange,提问作者Dmitry Bubnenkov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:24:03