Kotlin Callback形式のコードはCoroutine形式にラップしよう

18139 ワード

本記事の目的

前提として、本記事の内容は Kotlin を利用しているプロジェクトを対象に書いています。

最近では数が減ってきてはいますが、古いライブラリを利用していたり、歴史の長いプロジェクトでは Callback が今も活躍していると思います。

もちろんそれは悪いことではないのですが、Callback 形式のコードは Kotlin Coroutine でいい感じに書き直せるので今更ながら紹介します。(Coroutine の基礎的な非同期処理については割愛)

よくある Callback 形式のコード

まずはよくある Callback 形式を利用したコードを紹介します。

import kotlin.coroutines.*
import kotlinx.coroutines.*

class TestModel() {
    interface ResultListener {
        fun onSuccess()
        fun onFailure()
    }

    fun api1(listener: ResultListener) {
        Thread.sleep(5000)

        listener.onSuccess()
    }
}

fun main() {
    val testModel = TestModel()

    val callback = object: TestModel.ResultListener {
        override fun onSuccess() {
            print("success")
        }

        override fun onFailure() {
            print("failure")
        }
    }

    testModel.api1(callback)
}

動作を試す場合はこちら "https://pl.kotl.in/_zwwlvv-e"

今回 Test Model は自分で作成していますが、外部ライブラリと思っていただいてもいいと思います。

なんてことはない、普通のコードだと思いますが、「複数の Callback が連続する場合はネストが深くなり、メンテナンス性も低下する」という懸念を抱えています。
これは Kotlin に限らない話ですね。

そこで、Kotlin のとある機能を利用します。

SuspendCoroutine

suspendCoroutine を利用します。

これにより、非同期処理が終わるまでコルーチン内で待つことができます。