You need to enable JavaScript to run this app. Flutter如何实现一次API拉取数据供多个页面使用
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何实现一次API拉取数据供多个页面使用

Flutter 单次请求用户数据全局复用实现方案

核心思路是将请求到的用户数据存储在全局可访问的存储层,请求前先判断是否已有缓存,存在缓存直接返回,无缓存才发起接口请求,同时加锁避免并行场景下重复发起相同请求。


方案1:全局单例实现(最轻量,无需引入第三方库)

适合小型项目,无需额外依赖即可快速实现:

  • 首先定义单例类,封装用户数据存储、请求逻辑:
// 你自己定义的用户数据模型
class UserModel {
  final String userId;
  final String nickname;
  // 其他字段...
  UserModel.fromJson(Map<String, dynamic> json) : 
    userId = json['user_id'],
    nickname = json['nickname'];
}

class UserInfoSingleton {
  // 私有构造方法,禁止外部实例化
  UserInfoSingleton._internal();
  static final UserInfoSingleton _instance = UserInfoSingleton._internal();
  factory UserInfoSingleton() => _instance;

  UserModel? cachedUserInfo;
  bool _isRequesting = false; // 防重复请求标记

  // 全局统一调用的获取用户信息方法
  Future<UserModel?> fetchUserInfo({bool forceRefresh = false}) async {
    // 非强制刷新且已有缓存直接返回
    if (!forceRefresh && cachedUserInfo != null) return cachedUserInfo;
    // 已有正在进行的请求,等待请求完成后返回结果
    if (_isRequesting) {
      await Future.doWhile(() => Future.delayed(const Duration(milliseconds: 100), () => _isRequesting));
      return cachedUserInfo;
    }
    try {
      _isRequesting = true;
      // 替换为你自己的接口请求逻辑
      final response = await Dio().get('/api/user/detail');
      cachedUserInfo = UserModel.fromJson(response.data);
      return cachedUserInfo;
    } catch (e) {
      rethrow;
    } finally {
      _isRequesting = false;
    }
  }

  // 退出登录时调用清空缓存
  void clearCache() {
    cachedUserInfo = null;
  }
}
  • 任意页面需要用户数据时,直接调用UserInfoSingleton().fetchUserInfo()即可,首次调用会发起请求,后续所有调用直接返回缓存数据。

方案2:状态管理工具实现(适合中大型项目,需要响应式更新)

如果你项目中已经使用了Provider、Riverpod、Bloc、GetX等状态管理工具,直接用全局状态存储即可,逻辑和单例一致:

  • 在全局作用域定义用户数据相关的状态
  • 封装请求方法时加缓存判断、防重复请求逻辑
  • 所有页面直接读取/监听全局状态中的用户数据即可
    以Riverpod为例的极简实现:
final userInfoProvider = FutureProvider<UserModel?>((ref) async {
  // Riverpod默认会缓存Future返回结果,只要provider不被销毁就不会重复请求
  final response = await Dio().get('/api/user/detail');
  return UserModel.fromJson(response.data);
});

页面直接读取该provider即可,框架自动处理缓存复用。


方案3:InheritedWidget实现(原生方案,适合上层向下共享数据)

如果不想用单例也不想引入状态管理,可以在根路由或者上层路由中嵌套InheritedWidget存储用户数据,首次进入页面时发起请求存入组件,所有子页面都可以通过context直接获取数据,适合不需要频繁更新用户数据的场景。


注意事项

  • 遇到用户信息修改、切换账号等场景,可以调用方法时传入forceRefresh: true跳过缓存强制拉取最新数据
  • 用户退出登录时必须清空用户缓存,避免出现不同账号数据串用的问题
  • 必须加防重复请求标记,避免多个页面同时调用接口时触发多次相同请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 12:57:00