携手创作,一起成长!这是我参加「日新计划 8 月更文应战」的第14天,点击检查活动概况

本篇文章将是介绍flow一些常见API系列的开篇,期望能够帮助大家更好的把握flow运用,熟练的应用于各种场景。

历史文章

这些flow常见API的运用,你必定需求把握!(二)
这些flow常见API的运用,你必定需求把握!(三)
这些flow常见API的运用,你必定需求把握!(四)
这些flow常见API的运用,你必定需求把握!(五)

collect告诉flow履行

public suspend inline fun <T> Flow<T>.collect(crossinline action: suspend (value: T) -> Unit): Unit =
    collect(object : FlowCollector<T> {
        override suspend fun emit(value: T) = action(value)
    })

flow是冷流,只要调用collect{}办法时才能触发flow代码块的履行。还有一点要注意,collect{}办法是个suspend声明的办法,需求在协程效果域的规模能调用。

除此之外,collect{}办法的参数是一个被crossinline润饰的函数类型,旨在加强内联,禁止在该函数类型中直接运用return关键字(return@标签在外)。

fun main() {
    GlobalScope.launch {
        flow {
            emit("haha")
        }.collect {
        }
    }
}

launchIn()指定协程效果域告诉flow履行

public fun <T> Flow<T>.launchIn(scope: CoroutineScope): Job = scope.launch {
    collect() // tail-call
}

这个办法允许我们直接传入一个协程效果域的参数,不需求直接在外部敞开一个协程履行。本质上便是运用我们传入的协程效果域手动敞开一个协程代码块调用collect{}告诉协程履行。

这儿看官方的源码有个tail-call的注释,也便是尾调用的意思,猜测这儿可能官方会在这儿进行了优化,减少了栈中办法调用的层级,降低栈溢出的风险。

fun main() {
    flow {
        emit("haha")
    }.launchIn(GlobalScope)
}

catch{}捕捉反常

public fun <T> Flow<T>.catch(action: suspend FlowCollector<T>.(cause: Throwable) -> Unit): Flow<T> =
    flow {
        val exception = catchImpl(this)
        if (exception != null) action(exception)
    }

这个便是用来捕捉反常的,不过注意,只能捕捉catch()之前的反常,下面来个图阐述下:

这些flow常见API的使用,你一定需要掌握!(一)

即,只能捕捉第一个红框中的反常,而不能捕捉第二个红框中的反常。

merge()合流

public fun <T> merge(vararg flows: Flow<T>): Flow<T> = flows.asIterable().merge()

终究的完成类如下:

这些flow常见API的使用,你一定需要掌握!(一)

请注意,这个合流的每个流能够理解为是并行履行的,而不是后一个流等候前一个流中的flow代码块中的逻辑履行完毕再履行,这样做的目的能够提供合流的每个流的履行效果。

测验代码如下:

fun main() {
    GlobalScope.launch {
        merge(flow {
            delay(1000)
            emit(4)
        }, flow {
            println("flow2")
            delay(2000)
            emit(20)
        }).collect {
            println("collect value: $it")
        }
    }
}

输出日志如下:

这些flow常见API的使用,你一定需要掌握!(一)

map{}改换发送的数据类型

public inline fun <T, R> Flow<T>.map(crossinline transform: suspend (value: T) -> R): Flow<R> = transform { value ->
   return@transform emit(transform(value))
}

这个api没什么可将的,许多的地方比方调集、livedata中都有它的影子,它的效果便是将当时数据类型改换成另一种数据类型(能够相同)。

fun main() {
    GlobalScope.launch {
        flow {
            emit(5)
        }.map {
            "ha".repeat(it)
        }.collect {
            println("collect value: $it")
        }
    }
}

总结

本篇文章介绍了flow常见的api,接下来还会有一些列文章用来介绍flow的其他api,感谢阅览。