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

Dart异步代码同步化:解决重复异步请求低效问题

解决异步缓存重复请求问题

你的问题核心是当多个请求同时获取同一个未缓存资源时,会重复触发异步获取操作,造成性能浪费。通过维护一个记录"正在进行中请求"的映射表,就能让所有针对同一资源的并发请求复用同一个异步任务,避免重复执行。

修改后的完整代码:

import 'dart:async';

main() {
  IntStore intStore = IntStore();

  print("running getInt(A)");
  intStore.getInt("A");

  print("running getInt(A)");
  intStore.getInt("A");

  print("running getInt(B)");
  intStore.getInt("B");

  print("running getInt(A)");
  intStore.getInt("A");

  print("running getInt(C)");
  intStore.getInt("C");

  print("running getInt(D)");
  intStore.getInt("D");
}

class IntStore {
  final Map<String, int> _store = {};
  final Map<String, Future<int>> _inFlightRequests = {};

  Future<int> fetchInt(String intName) async {
    print("Fetching: $intName");
    await doSomeWorkAsynchronously(intName);
    return _store[intName]!;
  }

  Future<int> getInt(String intName) async {
    // 优先返回缓存内容
    if (_store.containsKey(intName)) {
      print("Cached: $intName");
      return _store[intName]!;
    }
    // 复用正在进行的请求
    if (_inFlightRequests.containsKey(intName)) {
      print("Waiting for in-flight request: $intName");
      return _inFlightRequests[intName]!;
    }
    // 发起新请求并记录到映射表
    final future = fetchInt(intName);
    _inFlightRequests[intName] = future;
    try {
      await future;
    } finally {
      // 请求完成后移除记录
      _inFlightRequests.remove(intName);
    }
    return _store[intName]!;
  }

  Future doSomeWorkAsynchronously(String intName) async {
    await Future.delayed(const Duration(seconds: 3));
    _store[intName] = 3;
    print("Fetched: $intName");
  }
}

关键改动说明

  • 新增_inFlightRequests映射表,存储每个资源对应的正在执行的异步请求Future
  • 在getInt方法中:
    1. 先检查缓存,存在则直接返回
    2. 若缓存不存在,检查是否有正在进行的请求,有则直接等待该请求完成,无需重复发起
    3. 若没有正在进行的请求,发起新请求并将Future存入映射表,请求完成后从表中移除

执行后的输出示例:

running getInt(A)
Fetching: A
running getInt(A)
Waiting for in-flight request: A
running getInt(B)
Fetching: B
running getInt(A)
Waiting for in-flight request: A
running getInt(C)
Fetching: C
running getInt(D)
Fetching: D
Fetched: A
Cached: A
Cached: A
Fetched: B
Fetched: C
Fetched: D

可以看到每个资源仅会被Fetching一次,后续并发请求都会等待同一个异步任务完成,彻底避免了重复操作带来的性能损耗。

内容的提问来源于stack exchange,提问作者George Gayton

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 20:10:31