【问题标题】:Coroutine doens't start?协程不启动?
【发布时间】:2020-04-12 05:51:53
【问题描述】:

基于这个postthrottleFirst函数:

fun <T> throttleFirst(
    skipMs: Long = 700L,
    scope: CoroutineScope = viewModelScope,
    action: (T) -> Unit
): (T) -> Unit {
    var throttleJob: Job? = null
    return { param: T ->
        if (throttleJob?.isCompleted != false) {
            throttleJob = coroutineScope.launch {
                destinationFunction(param)
                delay(skipMs)
            }
        }
    }
}

我是这样使用的:

查看

<Button
    android:onClick="@{viewModel.myClickListener}"
.../>

视图模型:

fun myClickListener() = View.OnClickListener { _ ->
    throttleClick(clickAction = {
        //do things
    })
}

BaseViewModel

protected fun throttleClick(millis: Long = 700L, clickAction: (Unit) -> Unit): (Unit) -> Unit  {
    throttleFirst(millis, scope = viewModelScope, action = clickAction)
}

但是什么也没发生,clickAction 没有到达。在调试时,当它到达return { param: T -&gt; 时,逐步结束,并且永远不会调用返回函数(throttleJob?.isCompleted... 代码)。
我做错了什么?

编辑Patrick的帮助下,最终的解决方案是:

视图模型

private val myThrottleClick = throttleClick(clickAction = {
    //do things
})

fun myClickListener() = View.OnClickListener { myThrottleClick(Unit) }

BaseViewModel

protected fun throttleClick(millis: Long = 700L, clickAction: (Unit) -> Unit): (Unit) -> Unit {
    return throttleFirst(millis, action = clickAction)
}

【问题讨论】:

  • 你在点击什么?
  • @coroutineDispatcher 帖子已更新。在来自 xml 的 Button 内使用。我正在使用Data Binding
  • 我认为throttleFirst(...) 的返回类型是一个函数引用(lambda)。你应该在代码中的某个地方调用它。 throttleFirst(..).invoke()

标签: android higher-order-functions kotlin-coroutines coroutinescope androidx-lifecycle


【解决方案1】:

您的throttleFirst 函数创建了一个点击侦听器,因此您必须将其存储在点击侦听器范围之外的 val 中。即

val clickListener = throttleFirst { doStuff() }

fun myClickListener() = View.OnClickListener { _ -> clickListener() }

您也许可以完全取消 myClickListener 函数,而只需在 xml 中引用 clickListener

【讨论】:

  • 好的,只缺少一件事,clickListener() 向我询问参数。我想使用 Unit 但我无法实例化“void”,那么您建议我如何解决这个小细节?
  • 您可以从 clickAction 中删除参数。 clickAction: () -> 单位。或者,您可以将 Unit 作为参数传递。
  • 我将使用第二种方法,因为我不想更改 throttleFirst 函数,而是创建一个“代理/助手”throttleClick 来使用它。也就是说,第二种方法是要遵循的:)我很愚蠢,因为我调用的是clickListener(Unit())而不是clickListener(Unit)...... ^^非常感谢Patrick!
猜你喜欢
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 2021-12-28
  • 2020-07-15
  • 1970-01-01
  • 2013-07-07
  • 2016-06-14
  • 1970-01-01
相关资源
最近更新 更多