Test status   stars   GitHub license  


缓存

带有内置代码生成的简单Flutter包。它简化并加速了dart类的缓存机制的创建。

最近最少使用(LRU)缓存算法

它是一个有限的键值对映射,使用最近最少使用(LRU)算法,其中“保留”最近使用过的项,“淘汰”旧的、较少使用的项,以便为新项腾出空间。

当您想限制内存使用,只保留常用项或缓存某些API调用时,它非常有用。

目录

动机

经常需要将某些内容缓存到内存中以供以后使用。常见的用例是缓存某些API调用及其响应。通常,这是在某个数据层中完成的,可能在——比如说——RemoteRepository中。

通常,存储库代码可能看起来像这样:

class RemoteRepository implements Repository {
  final SomeApiDataSource _dataSource;
  final SomeResponseType? cachedResponse;

  const RemoteRepository(this._dataSource);

  @override
  Future<SomeResponseType> getSthData() async {
    if (cachedResponse != null) {
      return cachedResponse;
    }

    cachedResponse = await _dataSource.getData();
    return cachedResponse;
  }
}

所以,我们不必手动执行此操作,而是可以使用库并以这种方式编写我们的RemoteRepository

@WithCache()
abstract class RemoteRepository implements Repository, _$RemoteRepository {
  factory RemoteRepository({required SomeApiDataSource dataSource,}) = _RemoteRepository;

  @Cached()
  Future<SomeResponseType> getSthData() {
    return dataSource.getData();
  }
}

设置

安装包

运行命令

flutter pub add --dev cached
flutter pub add cached_annotation

或者手动将依赖项添加到pubspec.yaml中:

dependencies:
  cached_annotation:

dev_dependencies:
  cached:

就这样!现在,您可以编写自己的缓存类了?

运行生成器

要运行代码生成器,请执行以下命令:

dart run build_runner build

对于Flutter项目,您可以运行:

flutter pub run build_runner build

请注意,与大多数代码生成器一样,[Cached]需要您同时导入注释([cached_annotation])并在文件的顶部使用part关键字。

因此,想要使用[Cached]的文件将以以下方式开头:

import 'package:cached_annotation/cached_annotation.dart';

part 'some_file.cached.dart';

基础

WithCache

Cached包的注释。

@WithCache注释一个类会将其标记为需要由Cached代码生成器处理。它可以接受一个额外的布尔参数useStaticCache。如果此参数设置为true,生成器将生成具有静态缓存的缓存类。这意味着该类的每个实例都将访问相同的缓存。默认值为false

缓存

标记为需要由Cached代码生成器处理的方法装饰器。

有3个可能的附加参数:

  • ttl – 生存时间。以秒为单位。设置缓存的有效期限。默认值为null,表示无限生存时间。
  • syncWrite – 仅影响异步方法(返回Future的方法)。如果设置为true,第一个方法调用将被缓存,如果后续(相同)调用发生,所有调用都将从第一次调用中获取结果。默认值为false
  • limit – 限制可以缓存多少个不同方法调用参数组合的结果。默认值为null,表示无限制。

IgnoreCache

此注释必须位于方法中的字段上方,并且必须是布尔值。如果为true,则将忽略缓存。

示例用法

  @cached
Future<int> getInt(String param, {@ignoreCache bool ignoreCache = false}) {
  return Future.value(1);
}

或者,您可以与useCacheOnError一起使用,如果设置为true,则在发生错误时返回上一个缓存的值。

  @cached
Future<int> getInt(String param, {@IgnoreCache(useCacheOnError: true) bool ignoreCache = false}) {
  return Future.value(1);
}

生成器可能出错的可能原因:

  • 如果方法有多个@ignoreCache注释

ClearCached

标记为需要由Cached代码生成器处理的方法装饰器。用此注释注解的方法可用于清除用Cached注释注解的方法的结果。此注释的构造函数可以接受一个可能的参数。它是方法名,我们想清除缓存。

假设存在一个已缓存的方法:

  @Cached()
Future<SomeResponseType> getUserData() {
  return userDataSource.getData();
}

要生成清除缓存的方法,我们可以写:

  @clearCached
void clearGetUserData();

或者

  @ClearCached('getUserData')
void clearUserData();

ClearCached参数或方法名必须与缓存的方法名相对应。我们还可以创建一个返回布尔值的方法,然后编写自己的逻辑来检查是否应清除缓存。

  @ClearCached('getUserData')
Future<bool> clearUserData() {
  return userDataSource.isLoggedOut();
};

如果用户注销,用户缓存将被清除。

生成器可能出错的可能原因:

  • 如果带有@cached注释的方法不存在
  • 如果配对的方法不存在
  • 如果方法不返回boolFuture<bool>void

ClearAllCached

这与ClearCached完全相同,不同之处在于您不传递任何参数,并且不在方法名称前添加清除语句,您所要做的就是将@clearAllCached放在方法上方,此注释将清除类中所有带有@WithCache的方法的缓存值。

这是一个简单的例子:

  @clearAllCached
void clearAllData();

或者,我们也可以创建一个返回布尔值的方法,然后编写自己的逻辑来检查是否将清除所有方法的缓存值。

  @clearAllCached
Future<bool> clearAllData() {
  return userDataSource.isLoggedOut();
};

如果用户注销,将清除所有方法的缓存值。

生成器可能出错的可能原因:

  • 如果我们有太多的clearAllCached注释,只能有一个
  • 如果方法不返回boolFuture<bool>void

贡献

我们接受对项目的任何贡献!

新功能的建议或修复应通过pull-request或issue创建。

功能请求

  • 检查功能是否已被处理或拒绝

  • 描述为何需要此功能

    只需创建一个带有enhancement标签和描述性标题的issue。然后,提供描述和/或示例代码。这将帮助社区理解其需求。

  • 为您的功能编写测试

    测试是解释建议功能如何工作的最佳方式。为了确保与现有代码库的一致性,我们在合并任何代码之前要求完整的测试。

  • 将其添加到README并为其编写文档

    将新功能添加到现有功能表中,并附加用法示例代码。

修复

  • 检查错误是否已被发现

  • 描述出了什么问题

    报告错误修复的最低要求是可重现的路径。编写应遵循的步骤来查找代码中的问题。最理想的情况是,您能完整地描述代码为何不起作用以及解决方案代码。

贡献者

GitHub

查看 Github