首页 > 解决方案 > Kotlin - 使用 ION 获取多个 JSON 文件时避免嵌套回调

问题描述

我有一些代码 1] 获取一个 JSON 文件,2] 根据该 JSON 文件的内容,获取另一个 JSON 文件。它使用离子库。

代码大致如下所示(旁注 - 此代码在onCreate我的活动方法上,并且e是类型的对象Exception):

Ion.with(applicationContext)
                .load("someURL")
                .asJsonObject()
                .setCallback { e, result->
                    //Do synchronous stuff with the "result" and "e" variables
                    //that determines whether boolean someCondition is true or false 

                    if(somecondition) {
                        Ion.with(applicationContext)
                                .load("https://raw.githubusercontent.com/vedantroy/image-test/master/index.json")
                                .asJsonObject()
                                .setCallback { e, result ->

                                    //Some synchronous code in here

                                }
                    } 

                }

这段代码非常难看,我想改进它以摆脱嵌套。那有可能吗,如果可以,我该怎么做?

我一直在试验,似乎我可以像这样调用该方法.then()setCallback其中.then()接受一个作为callback对象的参数:

Ion.with(applicationContext).load("someURL").setCallback { //Lambda Stuff }.then()

所以也许这将成为解决方案的一部分,但我不确定。

标签: androidkotlinasynccallbackandroid-ion

解决方案


Ion 项目有一个 Kotlin 协程模块:https ://github.com/koush/ion/tree/master/ion-kotlin ,但它似乎并未处于生产状态。幸运的是,在任何异步 API 和 Kotlin 协程之间添加自己的桥梁非常简单。

以下是如何为 Ion 执行此操作的示例:

private suspend fun fetchIon(url: String): String = suspendCoroutine { cont ->
    Ion.with(this)
            .load(url)
            .asString()
            .setCallback { e, result ->
                if (e != null) {
                    cont.resumeWithException(e)
                } else {
                    cont.resume(result)
                }
            }
}

现在你可以有这样的代码:

class MyActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        launch(UI) {
            if (fetchIon("example.org/now") > fetchIon("example.org/deadline") {
                ...
            }
        }
    }

如您所见,您执行异步 IO 代码就像它被阻塞一样。要处理错误,只需将其包装在 try-catch 中,就像任何“常规”代码一样。


推荐阅读