【Kotlin 协程】Flow 异步流 ⑥ ( 调用 Flow#launchIn 函数指定流收集协程 | 通过取消流收集所在的协程取消流 )

news2025/1/13 15:52:56

文章目录

  • 一、调用 Flow#launchIn 函数指定流收集协程
    • 1、指定流收集协程
    • 2、Flow#launchIn 函数原型
    • 3、代码示例
  • 二、通过取消流收集所在的协程取消流





一、调用 Flow#launchIn 函数指定流收集协程



1、指定流收集协程


响应式编程 , 是 基于事件驱动 的 , 在 Flow 流中会产生源源不断的事件 , 就是 发射元素操作 ;

拿到 Flow 流后 , 开始 收集元素 , 按照顺序逐个处理产生的事件 ( 元素 ) ;


调用 Flow#launchIn 函数 , 传入 协程作用域 作为参数 , 可以 指定 收集 Flow 流元素 的 协程 ;

在上一篇博客 【Kotlin 协程】Flow 异步流 ⑤ 中 , 调用 Flow#flowOn 函数 , 可以 指定 Flow 流发射元素 的 协程 ;


Flow#launchIn 函数返回值是 Job 对象 , 是 协程任务对象 , 可调用 Job#cancel 函数取消该协程任务 ;


2、Flow#launchIn 函数原型


Flow#launchIn 函数原型 :

/**
 * 终端流操作符,在[作用域]中[启动][启动]给定流的[收集][收集]。
 * 它是“范围”(scope)的简称。启动{flow.collect()} '。
 *
 * 此操作符通常与[onEach], [onCompletion]和[catch]操作符一起使用,以处理所有发出的值
 * 处理上游流或处理过程中可能发生的异常,例如:
 *
 * ```
 * flow
 *     .onEach { value -> updateUi(value) }
 *     .onCompletion { cause -> updateUi(if (cause == null) "Done" else "Failed") }
 *     .catch { cause -> LOG.error("Exception: $cause") }
 *     .launchIn(uiScope)
 * ```
 *
 * 注意,[launchIn]的结果值没有被使用,提供的作用域负责取消。
 */
public fun <T> Flow<T>.launchIn(scope: CoroutineScope): Job = scope.launch {
    collect() // tail-call
}

3、代码示例


代码示例 :

package kim.hsl.coroutine

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 携程中调用挂起函数返回一个 Flow 异步流
        runBlocking {
            println("流收集时的协程上下文 : ${Thread.currentThread().name}")

            flowEvent()
                .onEach {
                    // 逐个处理产生的事件
                    println("接收到事件 : $it, 当前线程 : ${Thread.currentThread().name}")
                }
                .launchIn(CoroutineScope(Dispatchers.IO)) // 在指定的协程作用域中处理收集元素操作,
                                                          // 该 launchIn 函数返回一个 Job 对象
                .join()     // 该协程不是 runBlocking 主协程 的子协程, 需要调用 join 等待协程执行完毕
        }
    }

    /**
     * 使用 flow 构建器 Flow 异步流
     * 产生事件的 事件源
     */
    suspend fun flowEvent() = (0..3)
        .asFlow()                               // 将区间转为 Flow 流
        .onEach {
            delay(500)
            println("发射事件 : $it, 当前线程 : ${Thread.currentThread().name}")
        }      // 发射元素 ( 产生事件 ) 时挂起 500ms
        .flowOn(Dispatchers.Default)           // 设置发射元素的协程
}

执行结果 :

2022-12-23 16:06:58.720 2950-2950/kim.hsl.coroutine I/System.out: 流收集时的协程上下文 : main
2022-12-23 16:06:59.345 2950-3080/kim.hsl.coroutine I/System.out: 发射事件 : 0, 当前线程 : DefaultDispatcher-worker-3
2022-12-23 16:06:59.347 2950-3078/kim.hsl.coroutine I/System.out: 接收到事件 : 0, 当前线程 : DefaultDispatcher-worker-1
2022-12-23 16:06:59.885 2950-3078/kim.hsl.coroutine I/System.out: 发射事件 : 1, 当前线程 : DefaultDispatcher-worker-1
2022-12-23 16:06:59.887 2950-3079/kim.hsl.coroutine I/System.out: 接收到事件 : 1, 当前线程 : DefaultDispatcher-worker-2
2022-12-23 16:07:00.394 2950-3080/kim.hsl.coroutine I/System.out: 发射事件 : 2, 当前线程 : DefaultDispatcher-worker-3
2022-12-23 16:07:00.396 2950-3080/kim.hsl.coroutine I/System.out: 接收到事件 : 2, 当前线程 : DefaultDispatcher-worker-3
2022-12-23 16:07:00.938 2950-3078/kim.hsl.coroutine I/System.out: 发射事件 : 3, 当前线程 : DefaultDispatcher-worker-1
2022-12-23 16:07:00.940 2950-3079/kim.hsl.coroutine I/System.out: 接收到事件 : 3, 当前线程 : DefaultDispatcher-worker-2

在这里插入图片描述





二、通过取消流收集所在的协程取消流



Flow 流的 收集元素 操作 , 是在协程中执行 , 将 协程 取消 , 即可将 Flow 流收集操作 取消 , 也就是 将 Flow 流取消 ;


代码示例 : 使用 withTimeoutOrNull(2000) 创建一个协程 , 该协程在 2000ms 后自动超时取消 , 同时在其中进行 流收集 的操作也一并取消 ;

package kim.hsl.coroutine

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 携程中调用挂起函数返回一个 Flow 异步流
        runBlocking {
            // 该协程作用域 2 秒后超时取消
            withTimeoutOrNull(2000){
                flowEvent().collect {
                    println("收集到元素 : $it")
                }
            }
            println("协程作用域取消")
        }
    }

    /**
     * 使用 flow 构建器 Flow 异步流
     * 产生事件的 事件源
     */
    suspend fun flowEvent() = (0..10)
        .asFlow()                               // 将区间转为 Flow 流
        .onEach {
            delay(500)
            println("发射事件 : $it, 当前线程 : ${Thread.currentThread().name}")
        }      // 发射元素 ( 产生事件 ) 时挂起 500ms
        .flowOn(Dispatchers.Default)           // 设置发射元素的协程
}

执行结果 :

2022-12-23 16:37:02.915 9585-9647/kim.hsl.coroutine I/System.out: 发射事件 : 0, 当前线程 : DefaultDispatcher-worker-1
2022-12-23 16:37:02.917 9585-9585/kim.hsl.coroutine I/System.out: 收集到元素 : 0
2022-12-23 16:37:03.429 9585-9647/kim.hsl.coroutine I/System.out: 发射事件 : 1, 当前线程 : DefaultDispatcher-worker-1
2022-12-23 16:37:03.431 9585-9585/kim.hsl.coroutine I/System.out: 收集到元素 : 1
2022-12-23 16:37:03.932 9585-9647/kim.hsl.coroutine I/System.out: 发射事件 : 2, 当前线程 : DefaultDispatcher-worker-1
2022-12-23 16:37:03.933 9585-9585/kim.hsl.coroutine I/System.out: 收集到元素 : 2
2022-12-23 16:37:04.327 9585-9585/kim.hsl.coroutine I/System.out: 协程作用域取消

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110235.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL的数据类型和存储引擎介绍

一. MySQL数据类型 1. 整数类型 注&#xff1a;MySQL可以为整数类型指定宽度&#xff0c;比如 int(3)、int(5)&#xff0c;这个限制不是限制value的合法范围&#xff0c;所以对绝大数应用没有任何意义&#xff0c;对于存储而言&#xff0c;int(3) 和 int(5) 是相同的&#xff…

机器学习中的数学原理——随机梯度下降法

这个专栏主要是用来分享一下我在机器学习中的学习笔记及一些感悟&#xff0c;也希望对你的学习有帮助哦&#xff01;感兴趣的小伙伴欢迎私信或者评论区留言&#xff01;这一篇就更新一下《白话机器学习中的数学——随机梯度下降法》&#xff01; 一、什么是随机梯度下降法 随机…

NVM安装

注意事项&#xff1a; 1、不能安装任何node版本&#xff08;如存在请删除后安装nvm&#xff09;; 安装步骤&#xff1a; 1、下载nvm ![在这里插入图片描述](https://img-blog.csdnimg.cn/c9dcc27383aa41888347080438c0914e.png 解压后点击exe文件进行安装&#xff1a; &#x…

负载均衡简介

一、什么是负载均衡&#xff1f; 互联网早期&#xff0c;业务流量比较小并且业务逻辑比较简单&#xff0c;单台服务器便可以满足基本的需求&#xff1b;但随着互联网的发展&#xff0c;业务流量越来越大并且业务逻辑也越来越复杂&#xff0c;单台机器的性能问题以及单点问题凸显…

SMMP:一种基于稳定成员资格的多峰聚类算法(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

伦茨LENZE GDC操作指南

1、GDC软件综述 GDC程序可以“在线模式”和“离线模式”使用&#xff1a; 离线模式 可以在没有与目标系统&#xff08;控制器&#xff09;相连接条件下使用。该功能允许离线设定参数、编程等工作。 在线模式 通过PC的串口、并口或系统总线实现GDC与目标系统&#xff08;控制器…

376. 机器任务——最小点覆盖+匈牙利算法

有两台机器 A&#xff0c;B 以及 K 个任务。 机器 A 有 N 种不同的模式&#xff08;模式 0∼N−1&#xff09;&#xff0c;机器 B 有 M 种不同的模式&#xff08;模式 0∼M−1&#xff09;。 两台机器最开始都处于模式 0。 每个任务既可以在 A 上执行&#xff0c;也可以在 B…

艾美捷游离巯基检测试剂盒基本参数和特点说明

游离硫醇&#xff08;即蛋白质上的游离半胱氨酸、谷胱甘肽和半胱氨酸残基&#xff09;的检测和测量是研究许多生物系统中的生物过程和事件的基本任务之一。 艾美捷游离巯基检测试剂盒提供了一种简单、可重复和灵敏的工具&#xff0c;用于测定样品&#xff08;即血浆、血清、组织…

3D格式转换工具HOOPS Exchange助力3D 打印软件实现质的飞跃

HOOPS SDK是用于3D工业软件开发的工具包&#xff0c;其中包括4款工具&#xff0c;分别是用于读取和写入30多种CAD文件格式的HOOPS Exchange、专注于Web端工程图形渲染的HOOPS Communicator、用于移动端和PC端工程图形渲染的HOOPS Visualize、支持将3D数据以原生3D PDF、HTML和标…

解决电脑C盘空间不足,发现微信和qq文件占用了大量内存

项目场景&#xff1a; 电脑C盘空间不足&#xff0c;需要隔一段时间清理垃圾&#xff0c;分析占用空间的文件&#xff0c;将C盘文件迁移到E盘。 问题描述 C盘提示空间不足 原因分析&#xff1a; 通过扫描磁盘发现微信和qq文件占用了几十G的内存&#xff0c;由于微信和qq的一…

C++成员函数当作参数调用的两种方式

平时编程时&#xff0c;多用来将数据进行传参&#xff0c;在考虑回调场景下我们会将函数单做参数传给被调用函数&#xff0c;让被调用函数在时机成熟时进行调用。在某些场景下&#xff0c;需要将类的成员函数当作参数进行回调&#xff0c;此时定义成员函数形参的方式通常有两种…

我的python学习经历及资源整理

对于小白来说&#xff0c;有个人引导会比自学要高效的多&#xff0c;尤其容易坚持不下去的小伙伴。可以试试下面这个入门课程&#xff0c;不用本地安装Python环境&#xff0c;能直接在网页上敲代码&#xff0c;还有大牛老师带着入门&#xff0c;能少走很多弯路&#xff01;只要…

直播弹幕系统(五)- 整合Stomp替换原生WebSocket方案探究

直播弹幕系统&#xff08;五&#xff09;- 整合Stomp替换原生WebSocket方案探究前言一. STOMP 协议简单介绍1.1 客户端编码基础1.2 服务端编码基础1.2.1 SimpMessagingTemplate1.2.2 SendTo 和 MessageMapping二. SpringBoot整合STOMP并实现聊天室2.1 基础配置和依赖2.2 WebSoc…

华为EC6108V9C免拆卡刷固件包

华为EC6108V9C免拆卡刷固件包 固件特点&#xff1a; 1、修改dns&#xff0c;三网通用&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、无开机广告&#xff0c;无系统更新&#xff0c;不在被强制升级&#xff1b; 4、大量精简内置的没用的软件&…

Redis高级篇之最佳实践

Redis高级篇之最佳实践 本章内容 Redis 键值设计批处理优化服务端优化集群最佳实践 笔记整理自 b站_黑马程序员Redis入门到实战教程 1. Redis键值设计 优雅的key结构 Redis 的 Key 虽然可以自定义&#xff0c;但最好遵循下面的几个最佳实践约定&#xff1a; 遵循基本格式&a…

Docker容器中安装Jenkins

众所周知,jenkins是现在比较流行的一种工具,今天就记录一下在工作中如何使用了jenkins&#xff0c; 由于我使用的使用Linux(Debain 11)开发环境使用了jdk1.8&#xff0c;会跟最新版的jenkins(官方介绍最新版要jdk11支持)有不良的化学反应&#xff0c;所以把jenkins放到了容器中…

Hive+Spark离线数仓工业项目实战--项目介绍及环境构建(2)

Docker的介绍 了解Docker的基本功能和设计 - 为什么要用Docker&#xff1f; - 什么是Docker&#xff1f; 路径 - step1&#xff1a;生产环境的问题 - step2&#xff1a;容器的概念 - step3&#xff1a;Docker的设计 实施 生产环境的问题 - 运维层面&#xff1a;一…

Windows下的通用进程守护程序(持续更新中),高仿supervisor。

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#x1f4e2;作者格言&#xff1a;无尽的折腾后&#xff0c;终于又回到…

【Three.js入门】标准网格材质、置换贴图、粗糙度贴图、金属贴图、法线贴图

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;也会涉及到服务端 &#x1f4c3;个人状态&#xff1a; 在校大学生一枚&#xff0c;已拿多个前端 offer&#xff08;秋招&#xff09; &#x1f680;未…

【实时数仓】DWS层的定位、DWS层之访客主题计算(PV、UV、跳出次数、计入页面数、连续访问时长)

文章目录一 DWS层与DWM层的设计1 设计思路2 需求梳理3 DWS层定位二 DWS层-访客主题计算1 需求分析与思路2 功能实现&#xff08;1&#xff09;封装VisitorStatsApp&#xff0c;读取Kafka各个流数据a 代码b 测试&#xff08;2&#xff09;合并数据流a 封装主题宽表实体类Visitor…