当前位置: 首页 > 知识库问答 >
问题:

创建发出侦听器回调结果的Kotlin coroutine延迟对象

葛承德
2023-03-14

我目前正在一个项目中从RxJava切换到Kotlin coroutines,用coroutine含水层替换所有单一和可观察的返回类型。我仍然在为以下结构而挣扎:一个接口(例如存储库的接口)提供数据查询访问并返回一个RxJava single。该实现使用Single.Create创建单个对象,并使用onSuccess/onError发出结果。现在,实现检索数据所需要做的是创建一个带有回调的侦听器,并将该侦听器注册到某个东西。然后,创建的侦听器的回调将在自创建的single上调用onsuccess/onerror。例如。使用firebase(尽管我的问题不是firebase特定的):

interface Repository {
    fun getData(query: Query): Single<DataSnapshot?>
}

fun getData(query: Query): Single<DataSnapshot?> = Single.create { emitter ->
    query.addListenerForSingleValueEvent(object : ValueEventListener {
        override fun onCancelled(error: DatabaseError?) {
            emitter.onError(Exception())
        }

        override fun onDataChange(data: DataSnapshot?) {
            emitter.onSuccess(data)
        }
    })
}

现在我想要的是返回coroutine deferred的html" target="_blank">接口方法。如何创建实现,以便还可以注册一个具有回调的侦听器,其结果将由延迟的?我看不出这些协同构建器(如async、launch等)能做onSuccess/onError会做的事情。

interface Repository {
    fun getData(query: Query): Deferred<DataSnapshot?>
}

共有1个答案

后烨煜
2023-03-14

我的建议如下:

interface Repository {
    suspend fun getData(query: Query): Result<DataSnapshot>
}

其中Result可能是一个包含成功和错误情况的密封类:

sealed class Result<T> {
    class Success<T>(result: T) : Result<T>()
    class Error<T>(error: String) : Result<T>()
}

这样,在getData的实现端,您可以做到:

return Success(yourData)
return Error("Something went wrong")

通常,在处理协程时,您应该避免返回deferred,并尝试将它们“作为同步方法”使用。

编辑:现在我明白了这个问题,我希望这有助于解决它:

//This is as generic as it gets, you could use it on any Query, no need to retype it
suspend fun Query.await(): DataSnapshot = suspendCoroutine{cont ->
    addListenerForSingleValueEvent(object : ValueEventListener{
        override fun onCancelled(error: DatabaseError?) {
            cont.resumeWithException(error?: Exception("Unknown Error"))
        }

        override fun onDataChange(data: DataSnapshot?) {
            if(data != null){
                cont.resume(data)
            } else {
                cont.resumeWithException(Exception("Null data"))
            }

        }
    })
}
//this is your actual implementation
suspend fun getData(query: Query):DataSnapshot =
        query.await()

此代码假设DatabaseError extends Exception或Throwable。如果不是,您需要为它创建一个包装类型,或者使用我的原始解决方案,并且在这两种情况下都使用常规的简历

 类似资料:
  • 我创建了一个应用程序,其中一个地点列表保存在数据库中。我只根据Google留档保存了保存地点的地点ID。 然后我创建了一个界面,让用户输入他们的当前位置(mCurrentLocation)。 然后,我创建了一个异步任务,检查数据库中保存的每个地点ID,并检查哪些地点距离用户位置500米以内。这是在doInBackground中完成的。根据Google文档,我使用了getPlaceById和setR

  • 我需要在一定的持续时间后将消息发送给MessageListener,所以有没有任何方法可以使用SpringAMQP实现。 如。Producer生成消息并将消息发送到RabbitMQ Q,该消息立即被侦听器接收到,我想延迟消费者端接收到的消息,比如说在一些配置参数(比如1000ms)之后

  • 在我的控制器中,我返回由另一个线程填充的延迟结果: FooController.java 页面准备者.java 显然,再次调用所有筛选器以“完成”请求。我的一个过滤器,需要访问 豆,这是请求范围的。该调用引发异常 查看我配置的异常: 但是没有区别。我该怎么解决这个问题?

  • 我们定义了一个testng结果侦听器,它帮助我们将testng.xml中定义的每个测试用例的测试结果发送到一个内部工具,如下所示: } 然后我们将这个侦听器集成到其他项目的testng xml文件中,例如: 它按照设计工作:一旦测试套件完成,测试结果将上传到内部工具。 现在我们有一个要求,在一个项目中,testng.xml中的一个测试用例与内部工具中的3个测试用例相关,这意味着对于testng.x

  • 我在JMeter中有一个性能测试。我有一些SSH监听器,它们应该检索CPU和RAM的使用情况。我希望得到一个关于Jmeter在测试运行时收集侦听器值所使用的延迟的明确解释。用户是否可以设置延迟值?如果可以,Jmeter支持的最小值是多少。目前的数据收集监听器是有点随机的,我认为这是不好的。目前,我在结果中没有类似数量的条目,尽管在两个监听器中我有相同数量的命令。我试图将jmeter.propert

  • Flask 的设计原则中有一条是响应对象被创建并在一条可能的回调链中传递,而在 这条回调链但中的任意一个回调,您都可以修改或者替换掉他们。当请求开始被 处理时,还没有响应对象,响应对象将在这一过程中,被某个视图函数或者系统 的其他组件按照实际需要来闯将。 但是,如果您想在响应过程的结尾修改响应对象,但是这是对象还不存在,那么会发生 什么呢?一个常见的例子是您可能需要在 before-request