在 kotlin 中何时一起使用挂起函数和 Flow 或分开使用?

2024-04-13

在审查用 kotlin 编写的一些代码时,有件事引起了我的注意。我在一些项目中查看领域层,在一些项目中,我看到挂起功能和 Flow 一起使用,而在一些项目中,我看到只使用 Flow。

例如暂停和流动在一起 :

class FetchMovieDetailFlowUseCase @Inject constructor(
    private val repository: MovieRepository
) : FlowUseCase<FetchMovieDetailFlowUseCase.Params, State<MovieDetailUiModel>>() {

    data class Params(val id: Long)

    override suspend fun execute(params: Params): Flow<State<MovieDetailUiModel>> =
        repository.fetchMovieDetailFlow(params.id)
}

只是流动

class GetCoinUseCase @Inject constructor(
    private val repository: CoinRepository
){
 
    operator fun invoke(coinId:String): Flow<Resource<CoinDetail>> = flow {

        try {
            emit(Resource.Loading())
            emit(Resource.Success(coin))

        }catch (e:HttpException){
            emit(Resource.Error(e.localizedMessage ?: "An unexpected error occured"))
        }catch (e:IOException){
            emit(Resource.Error("Couldn't reach server. Check your internet connection."))
        }
    }
}

只是暂停

class GetLatestNewsWithAuthorsUseCase(
  private val newsRepository: NewsRepository,
  private val authorsRepository: AuthorsRepository,
  private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
) {
    suspend operator fun invoke(): List<ArticleWithAuthor> =
        withContext(defaultDispatcher) {
            val news = newsRepository.fetchLatestNews()
            val result: MutableList<ArticleWithAuthor> = mutableListOf()
            // This is not parallelized, the use case is linearly slow.
            for (article in news) {
                // The repository exposes suspend functions
                val author = authorsRepository.getAuthor(article.authorId)
                result.add(ArticleWithAuthor(article, author))
            }
            result
        }
}

这三个都是不同的项目,不要被代码所困扰,这些只是我遇到过的项目,我分享是为了展示示例,但我想在这里提请您注意的是,有时只有暂停使用function,有时只使用Flow,有时两者都使用。这是什么原因呢?你能详细解释一下吗? 我试图将其纳入我的逻辑


suspend函数对于以暂停、同步的方式检索单个项目是有意义的。

当您决定开始收集时,流程会随着时间的推移返回多个项目。它们通常用于监视随时间变化的事物,以检索事物的最新值。例如,每次数据库中的某些内容发生更改时,来自数据库的流都可以发出新值。

使用检索 Flow 的挂起函数将两者结合起来几乎没有意义。这是因为 Flow 本身是一个轻量级对象,通常不需要任何前期、耗时的工作来检索和创建。

避免创建函数的原因suspend当返回流时,它使得使用起来更加麻烦。在某些情况下,您可能希望传递流而不收集它,并且您不希望仅仅为了获取流而启动协程。或者,您可能只想使用这种漂亮、简洁的语法来创建专用的集合协程:

someUseCase.retrieveSomeFlow()
    .onEach { ... }
    .launchIn(someScope)

代替:

someScope.launch {
    someUseCase.retrieveSomeFlow().collect {
        ...
    }
}

如果您必须检索某些内容作为流程基础的密钥,则可能会出现例外情况。例如,从 API 检索用户 ID,然后返回使用该用户 ID 来获取流的项目的流。但即使这样通常也是不必要的,因为您可以将该 ID 检索放入流程中。例如:

fun getUserItems(): Flow<UserItem> = flow {
    val userId = someAPI.retrieveUserId() // calling a suspend function
    emitAll(someAPI.getUserItemsFlow(userId))
}

这样做的唯一缺点是,如果多次收集流量,则每次开始收集时都必须重新检索用户 ID。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 kotlin 中何时一起使用挂起函数和 Flow 或分开使用? 的相关文章

随机推荐

  • 仅当单个 NaN 时才进行插值

    pandas 有没有办法只插入单个缺失的数据点 也就是说 如果有 2 个以上连续的 NaN 我想不理会它们 所以 举个例子 s pd Series 1 None 2 3 None None 4 5 d interpolate limit 1
  • 没有足够的配额来处理此命令 -WPF

    我正在开发 WPF 应用程序 我已经为此应用程序实现了错误处理并实现了错误邮件发送功能 因此 如果应用程序发生任何错误 管理员将收到错误消息 我的问题是我们总是收到以下错误消息 Error 没有足够的配额来处理此命令 MS Win32 Un
  • xml 格式变化时的 xpath 查询

    我有一系列变量类型 例如 abc1A abc1B abc3B xyz1A xyz2A xyz3C data1C data2A 以多种xml格式存储 area
  • 系统虚拟化:了解 IO 虚拟化和虚拟机管理程序的作用 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想对I O虚拟化有一个正确的理解 上下文是纯 全虚拟化 而不是半虚拟化 我的理解是 虚拟机管理程序虚拟化硬件并向每个沙盒应用程序提供虚拟资源 每个沙
  • 检测“位图中”的形状

    所以 在为下一场 ieextreme 比赛做准备时 我遇到了一些过去的问题 我发现一个真正困扰我的问题 因为我不知道该怎么做 我可能可以使用一些 300 行的暴力代码来实现它 但我我认为这不是在这样的比赛中应该做的事情 所以我需要你的帮助
  • 防止直接访问网站某些目录的最佳方法是什么?

    防止直接访问网站的某些目录的最佳方法是什么 1 创建并放置 htaccess我们要保护的每个目录中的文件并将下一行放入其中 Deny from all 2 创建并放置index php我们要保护的每个目录中的文件 并仅在其中放置下一行代码
  • 内部文件夹中的 ASP.NET Server.Mappath 问题

    我有一个 ASP NET 应用程序 在 APP Code 文件夹中我有一个类 我有以下代码来读取根文件夹中 XML 文件的内容 XmlDocument xmlSiteConfig new XmlDocument xmlSiteConfig
  • 了解皮尔逊相关系数

    作为生成计算的一部分皮尔逊相关系数 http devlicio us blogs billy mccafferty archive 2006 11 07 netflix memoirs using the pearson correlati
  • Rails 替换集合,而不是从 has_many 嵌套属性表单添加到集合中

    我有这些模型 为了便于阅读而简化 class Place lt ActiveRecord Base has many business hours dependent destroy accepts nested attributes fo
  • 在 JSF 中使用 JPA 实体。防止 LazyInitializationException 的最佳策略是什么?

    希望听取专家关于从 JSF UI 编辑 JPA 实体的最佳实践的意见 所以 关于这个问题 我要说几句话 想象一下我有持久化的对象MyEntity我获取它进行编辑 在 DAO 层我使用 return em find MyEntity clas
  • 如何使用文件实现循环缓冲区?

    我的应用程序 C 程序 打开同一文件的两个文件句柄 一个处于写入模式 一个处于读取模式 应用程序中的两个单独的线程读取和写入文件 这很好用 由于我的应用程序在 RAM 磁盘大小有限的嵌入式设备上运行 我想写FileHandle在达到最大大小
  • 如何按用途自动对类中的函数进行排序?

    a Robert C Martin 的 Clean Code 一书建议根据 降级规则 对函数进行排序 我们希望代码读起来像自上而下的叙述 我们想要每一个 函数之后是下一个抽象级别的函数 因此 我们可以读取该程序 下降一个抽象级别 我们阅读函
  • 交换 img src 或显示/隐藏多个图像是否更快?

    在网页上交换图像时使用的最佳做法是什么 更改图像源或只是在页面上显示 隐藏多个图像 为了平衡速度 你必须做出选择 有两个选择 更改图像源 这样 页面加载速度会更快 因为它只获取可见图像 但当您更改 src 属性时 显示新图像将花费更长的时间
  • 如何创建具有逐字环境的新 Beamer 环境?

    我正在创建一个 Beamer 演示文稿 其中包含大量 LaTeX 示例 并且必须在逐字环境中进行 我厌倦了打字 begin example begin verbatim Verbatim Text end verbatim end exam
  • 对于大输入,十进制扩展程序运行速度非常慢

    我正在编写一个程序来计算数字的小数扩展103993 33102我想根据用户输入的数字打印出所有尾随小数 它可以快速运行所有数量最多10 5但如果输入10 6编程大约需要 5 分钟才能打印出答案 我怎样才能加快速度 我尝试了两种不同的方法 一
  • Java从ZipInputStream条目创建InputStream

    我想编写一个从单个 InputStream 读取 ZIP 内的多个 XML 文件的方法 该方法将打开一个 ZipInputStream 并在每个 xml 文件上获取相应的 InputStream 并将其提供给我的 XML 解析器 这是该方法
  • 基于 Django 年/月的帖子存档

    我是 Django 新手并启动了一个应用程序 我做了模型 视图 模板 但我想在底部添加某种存档 页面的内容 类似这样http www flickr com photos ionutgabriel 3990015411 http www fl
  • JPA实体扩展类包含@Id

    我有实体类都包含 id 作为主键 我可以创建包含所有公共字段的抽象类并允许所有类扩展该类 如下所示 public abstract class CommonFields Id Column name ID private long id p
  • 不可能:没有附加布局管理器;跳过布局

    我完全迷失了这个错误 我理解它 但我不知道出了什么问题 对于代码 In the OnCreate of my activity historyRecyclerView RecyclerView findViewById R id recyc
  • 在 kotlin 中何时一起使用挂起函数和 Flow 或分开使用?

    在审查用 kotlin 编写的一些代码时 有件事引起了我的注意 我在一些项目中查看领域层 在一些项目中 我看到挂起功能和 Flow 一起使用 而在一些项目中 我看到只使用 Flow 例如暂停和流动在一起 class FetchMovieDe