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

Flutter中如何仅调用一次Rest API并复用内存数据

优化方案:单次API调用+内存缓存读取产品数据

1. 创建全局内存缓存单例

用单例类存储产品数据,确保整个APP内只有一份缓存实例,避免重复请求:

class ProductCache {
  static final ProductCache _instance = ProductCache._internal();
  List<PostListOfProducts>? _cachedProducts;

  factory ProductCache() => _instance;

  ProductCache._internal();

  // 存入缓存数据
  void setProducts(List<PostListOfProducts> products) {
    _cachedProducts = products;
  }

  // 获取缓存数据
  List<PostListOfProducts>? getProducts() {
    return _cachedProducts;
  }

  // 登出时清空缓存,避免用户数据混淆
  void clearCache() {
    _cachedProducts = null;
  }
}

2. 修改API请求逻辑,优先读取缓存

修改getPosts方法,先检查缓存,无缓存时再发起API请求,成功后存入缓存:

static Future<List<PostListOfProducts>> getPosts() async {
  // 先读缓存,有数据直接返回
  final cachedProducts = ProductCache().getProducts();
  if (cachedProducts != null) {
    return cachedProducts;
  }

  SharedPreferences prefs = await SharedPreferences.getInstance();
  final token = await prefs.getString('token');
  final loginEmail = await prefs.getString('dietetyk');
          
  Response response = await post(Uri.parse('https://some_page.com'),
    headers: <String, String>{
      'Accept': 'application/json',
      'Authorization': 'Bearer $token',
    },
    body: <String, String>{
      'loginEmail': loginEmail,
    },
  );
         
  if(response.statusCode != 200){
    print('Błąd połączenia z bazą danych...  status[${response.statusCode}]');
    throw Exception('Nie udało się załadować produktów');
  }
         
  final List body = json.decode(response.body);
  final products = body.map((e) => PostListOfProducts.fromJson(e)).toList();
  // 请求成功后存入缓存
  ProductCache().setProducts(products);
  return products;
}

同时修改PostListOfProductsAPI的搜索逻辑,直接从缓存过滤数据,不再重复发起API请求:

class PostListOfProductsAPI {
  static Future<List<PostListOfProducts>> getUserSuggestions(String query) async {
    // 先读缓存,缓存为空则先调用getPosts获取数据
    final cachedProducts = ProductCache().getProducts() ?? await getPosts();
    return _filterProducts(cachedProducts, query);
  }

  // 抽离搜索过滤逻辑
  static List<PostListOfProducts> _filterProducts(List<PostListOfProducts> products, String query) {
    final queryLower = query.toLowerCase();
    return products.where((product) => 
      product.nazwa!.toLowerCase().contains(queryLower)
    ).toList();
  }
}

3. 优化页面FutureBuilder的使用

避免将postsFuture定义为顶级变量(页面重建时会重复触发请求),改为在initState中初始化:

late Future<List<PostListOfProducts>> postsFuture;

@override
void initState() {
  super.initState();
  postsFuture = getPosts();
}

// 原build方法保持不变
Widget build(BuildContext context) {
  return Scaffold(
    // ... 原有代码
    body: FutureBuilder<List<PostListOfProducts>>(
      future: postsFuture,
      builder: (context, snapshot) {
        // ... 原有builder逻辑
      },
    ),
  );
}

4. 登出时清空缓存

在signUserOut方法中加入清空缓存的逻辑,防止切换用户后数据残留:

void signUserOut() async {
  // 原有登出逻辑
  await FirebaseAuth.instance.signOut();
  // 清空产品缓存
  ProductCache().clearCache();
  // 跳转到登录页等后续操作
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:54:53