【问题标题】:Is it possible to stop the flow 's collection from collect's code block?是否可以从收集的代码块中停止 flow 的收集?
【发布时间】:2022-01-02 07:36:21
【问题描述】:

我是协程/流的新手,想知道在collect 的代码块获得所需值时关闭流的适当方法。

如下代码:

suspend fun findService(scope:CoroutineScope, context:Context, name:String) {
  val flow = getWifiDebuggingConnectDiscoveryFlow( context )
  try {
    flow.collect {
      if(name == it.serviceName)  {
        /* need to exit the collection and execute the code that follows */
      }
    }
    println("service found!")
  } catch(e: Throwable) {
    println("Exception from the flow: $e")
  }

  /* need to do something after service found */

}

private fun getWifiDebuggingConnectDiscoveryFlow(context:Context) = callbackFlow {
  val nsdManager:NsdManager = context.getSystemService(Context.NSD_SERVICE) as NsdManager
  val listener = object : NsdManager.DiscoveryListener {
    override fun onStartDiscoveryFailed(serviceType: String?, errorCode: Int) {cancel("onStartDiscoveryFailed")}
    override fun onStopDiscoveryFailed(serviceType: String?, errorCode: Int) {cancel("onStopDiscoveryFailed")}
    override fun onDiscoveryStarted(serviceType: String?) {}
    override fun onDiscoveryStopped(serviceType: String?) {}
    override fun onServiceLost(serviceInfo: NsdServiceInfo?) {}

    override fun onServiceFound(serviceInfo: NsdServiceInfo?) {
      if(serviceInfo==null) return
      trySend(serviceInfo)
    }
  }
  nsdManager.discoverServices(ServiceDiscovery.ADB_CONNECT_TYPE, NsdManager.PROTOCOL_DNS_SD, listener)
  awaitClose { nsdManager.stopServiceDiscovery(listener) }
}

这个问题困扰了我很长时间,如果能得到任何帮助,我将不胜感激。

【问题讨论】:

    标签: kotlin kotlin-coroutines


    【解决方案1】:

    您可以使用firstfirstOrNull 运算符。一旦收到符合条件的第一个元素,它将立即停止收集:

    val service = flow.firstOrNull { name == it.serviceName }
        ...
    

    你可以找到first官方文档here

    【讨论】:

    • 是的,它成功了,谢谢格伦
    猜你喜欢
    • 2011-03-05
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 2013-12-29
    • 2022-06-18
    • 2021-05-27
    • 1970-01-01
    相关资源
    最近更新 更多