在Kotlin中传递多个lambda函数以处理成功/失败的最佳方法

时间:2018-05-23 23:19:33

标签: android kotlin

Kotlin在这里新学,并尝试学习使用高阶函数和传递lambda的最佳方法。我已创建此方法来调用API并返回从字符串创建的对象,如果出现错误则返回失败。

    fun getDeviceStatus(onSuccess: (Device) -> Unit, onFailure: ((String) -> Unit)? = null) {

        FuelClient.get(DEVICE_URL,
                success = { responseString ->

                    val adapter = MoshiUtil.moshi.adapter(Device::class.java)

                    val deivce= adapter.fromJson(responseString)!!

                    onSuccess(device)
                },
                failure = { onFailure?.invoke(it.message!!)})


    }

我可以像这样使用这个功能:

DeviceService.getDeviceStatus(
                { w ->
                    print("device")
                },
                { e -> print(e) })

但令我烦恼的是,我无法看到函数的名称,看看每个函数的作用。我想知道是否有更清洁/更好的方法来做到这一点,比如

DeviceService.getDeviceStatus(){
            onSuccess{print("device")}
            onFailure{print("error")}
        }

或者

DeviceService.getDeviceStatus()
                .onSuccess{print("device")}
                .onFailure{print("error")}

但那些错误。有关如何最好地处理onSuccess / onFailure用例的任何想法很常见吗? THX

2 个答案:

答案 0 :(得分:0)

对于这种特定情况,当第二个lambda是可选的时,infix函数可以很好地工作:

sealed class DeviceStatusResult {
    abstract infix fun onFailure(handler: (String) -> Unit)
}

class DeviceStatusSuccess(val device: Device) : DeviceStatusResult() {
    override fun onFailure(handler: (String) -> Unit) = Unit
}

class DeviceStatusFailure(val errorMessage: String) : DeviceStatusResult() {
    override fun onFailure(handler: (String) -> Unit) = handler(errorMessage)
}

fun getDeviceStatus(onSuccess: (Device) -> Unit): DeviceStatusResult {
    // get device status
    // if (success)
    val device = Device()
    onSuccess(device)
    return DeviceStatusSuccess(device)
    // else
    // return DeviceStatusFailure(message)
}

然后可以像

一样使用
getDeviceStatus { device ->
    println(device)
} onFailure { errorMessage ->
    System.err.println(errorMessage)
}

也许onFailure应该叫orFail或类似的名称。

第二个参数为可选时,这是很好的选择,但不是那么多,因为它不会强迫用户实际提供故障处理程序。而且我认为这不是一个好主意,因为它很容易意外地忽略故障处理程序。最好强迫用户提供一个,即使它恰好是一个空的。因此,在这种情况下,最好使用命名参数,即使没有强制要求实际命名它们的情况。

答案 1 :(得分:0)

例如我们有一个类需要有多个函数,例如两个函数作为参数:

class TestClass internal constructor(
  private val onClickShowName: (String) -> Unit,
  private val onClickShowSurname: (String) -> Unit
) { //Your work. }

然后你需要创建 val 作为 TestClass:

class MainActivity {
    val mTestClass = TestClass(
        onClickShowName = {dataText: String -> Log.i("CANER", dataText)},
        onClickShowSurname = {dataText: String -> Log.i("CANER", dataText)}
    )
}