iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
Mobile Development

Kotlin 全面啟動 系列 第 13

[Kotlin 全面啟動] Coroutine II

  • 分享至 

  • xImage
  •  

昨天我們談了蠻多概念的,今天就讓我們具體談 Coroutine 的實作細節吧!

Suspend function

Suspend 是使用 Coroutine 的一個重要的保留關鍵字,用來作為讓 compiler 以及開發者識別目前是否在 Coroutine 中的一個判斷,任何的 function 都可以在他的前面加上 suspend 來讓他變成 suspend function,而其他地方如果要呼叫這個 function 就必須在某個 suspend function 或是 coroutineScope 中,比如以下的範例:

fun normalFunction() {
    test() // this will not compile!!
}

suspend fun suspendFunction() {
    test() // this will compile!!
}

suspend fun test() {
    //...
}

如果你熟悉 Comose 的話,可能會覺得概念以及結構很類似對吧!

第一個 function 會帶出以下的錯誤:

Suspend function 'coroutineFunction' should be called only from a coroutine or another suspend function

好,那為什麼要這樣設計呢,主要是因為 suspend function 就如它的名字所示,執行的時候是可能會中斷跳出讓別人先執行後再回來繼續執行的,比如以下的程式碼就會先印出 Hello world! 後等一秒再繼續印出 Hello world 2!

suspend fun test() {
    println("Hello World!")
    delay(1000L)
    println("Hello World 2!")
}

目前 Coroutine 的做法是在 compile 時多加一個參數紀錄執行到哪一個區間以及當時的環境變數值,然後把 function 內的程式碼分成多段以便隨時中斷。所以當 suspend function 呼叫 suspend function 時就可以把這個參數繼續往下傳,但如果是一般的 function,因為他沒有這個參數,compiler 自然也就不知道怎麼 compile 囉。

作為上層的開發者,其實我們不需要太擔心 suspend 的實作細節,而且也不應該依賴於底層的實作細節以免哪天改了上層就壞掉,但如果有大概的 mindset,也會讓我們更容易的去理解這個工具唷!

NonBlocking

Suspend function 還有個重要的概念是 non-blocking,當我們使用 Thread.sleep 的時候,sleep 會真的把目前的 Thread 停下來,但使用 delay 就不會,只是把目前的 function 先回傳,等下次該執行的時候再呼叫同個 function 就好,也因此使用起來的效率會更高。

Launch Coroutine

既然 suspend function 只能被其他的 suspend function 呼叫,那在雞生蛋、蛋生雞的循環裡,誰是第一個雞、或是第一個蛋呢?

大家可以翻翻看昨天的範例裡,我們通常是使用 runBlocking 這個 function 的 lambda block 來呼叫 suspend function,這好處是非常簡單就可以介接 Coroutine 跟一般的 function,但缺點就是 runBlocking 需要 block 目前的 Thread,等到 Coroutine 都執行完才能繼續走到 runBlocking 的下一行程式碼。

另一種方法是使用 CoroutineScope 的 launch,顧名思義 launch 呼叫後跟原本的 function block 就不太有關係了,除了等待執行完成,也可以透過 launch 回傳的 job 物件呼叫 cancel 來強制中斷,或是呼叫 CoroutineScope 的 cancel。

fun main() = runBlocking {
    val job = launch {
        ...
    }
    job.cancel()
    println("Hello")
}

大家如果翻一下程式碼,會發現 CoroutineScope 的 cancel 內部也是使用 job 的 cancel 喔 XD

Coroutine 真的有太多事情可以分享了,明天我們再繼續介紹怎麼使用 Coroutine 切換 Thread,把非同步的程式寫的跟一般程式一樣,以及 Android / iOS 上的使用。


上一篇
[Kotlin 全面啟動] Coroutine
下一篇
[Kotlin 全面啟動] Coroutine III
系列文
Kotlin 全面啟動 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言