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方法中:- 先检查缓存,存在则直接返回
- 若缓存不存在,检查是否有正在进行的请求,有则直接等待该请求完成,无需重复发起
- 若没有正在进行的请求,发起新请求并将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
相关产品推荐
相关产品推荐

