syncFromEvent

inline suspend fun <E : Event, R : Any> EventChannel<*>.syncFromEvent(priority: EventPriority = EventPriority.NORMAL, noinline mapper: suspend (E) -> R?): R

挂起当前协程, 监听事件 E, 并尝试从这个事件中获取一个值, 在超时时抛出 TimeoutCancellationException

本函数是 EventChannel.subscribe 的衍生工具函数, 内部会调用 EventChannel.subscribe.

挂起可取消

本函数的挂起过程可以被取消. 这意味着若在 CoroutineScope.launch 中使用本函数, 则 launch 启动的 Job 可以通过 Job.cancel 取消 (停止), 届时本函数会抛出 CancellationException.

异常处理

filter 抛出的异常属于监听方异常, 将会由 nextEvent 原样重新抛出.

使用 Flow 的替代方法

在 Kotlin 可使用 EventChannel.asFlow 配合 Flow.filterFlow.first 实现与 nextEvent 相似的功能 (注意, Flow 方法将会使用 EventPriority.MONITOR 优先级).

示例:

val senderId: Long = GlobalEventChannel.asFlow()
.filterIsInstance<GroupMessageEvent>()
.filter { it.sender.id == 123456L }
.map { it.sender.id }.first()

// 上下代码等价

val senderId: Long = GlobalEventChannel
.filterIsInstance<GroupMessageEvent>()
.syncFromEvent(EventPriority.MONITOR) { if (it.sender.id = 123456) it.sender.name else null }

由于 Flow 拥有更多操作且逻辑更清晰, 在不需要指定事件优先级时更推荐使用 Flow.

Since

2.10

See also

普通地监听一个事件

挂起当前协程, 并获取下一个事件实例

Parameters

mapper

过滤转换器. 返回非 null 则代表得到了需要的值. syncFromEvent 会返回这个值

Throws

mapper 抛出任何异常时, 本函数会抛出该异常