iT邦幫忙

2021 iThome 鐵人賽

DAY 1
1

Hi 各位好,又到了我們一年一度的 iT邦鐵人賽的挑戰,這次我所挑戰的主題是 Kotlin 中用來處理非同步的 lib Coroutine,中文名稱「協程」,是與 Kotlin 1.3 版一起推出的一個函式庫,正式版推出時間距今已經快要有三年的時間,目前在 github 也已經累積 9.7k 顆星。

Coroutine 推出之後,很多 Kotlin 開發者開始使用 Coroutine,究竟 Coroutine 有什麼樣的魅力,可以讓 Kotlin 開發者對 Coroutines 趨之若鶩呢?

在三十天中,我們將會一一討論 Coroutine,包括 CoroutineScope、Coroutine Builder、Suspend function、channel、flow... 。


前言

在開始進行 Coroutine 的討論之前,我們要先來了解 Coroutine 是要用來解決什麼問題。(文末解答XD)

首先,根據程式的執行順序可以分為兩種形式,一種是同步 (Synchronous)的、另一種為非同步(Asynchronous),也稱為異步。

同步

同步是根據程式碼的順序來執行。同步的程式是容易的、直覺的,只要將程式碼按照想要執行的順序依序編寫就可以了。
同步程序圖

如上, 用同步的方式依序執行三段程式,程式的執行時間就會是 function A 所執行的時間+ function B 所執行的時間 + function C 所執行的時間。一段程式執行完之後,才會執行下一段程式。

這就像是田徑場上的接力賽的感覺,一棒接一棒。

https://media.giphy.com/media/glqdZPHSpcMNTbhCxs/giphy.gif

非同步

非同步的概念則是與同步相異,程式碼不是依照程式碼的順序來執行並得到結果。當需要執行的程式需要比較多的時間,為了避免卡住畫面,會將程式碼在另外的執行緒上執行,等到完成之後告訴主執行緒、又或者是不知道什麼時候可以取得結果(例如與 Server 取值)。

如下圖,向 Server 取值的時序圖:

當 Client 向 Server 發出一個請求時,因為是採用非同步的方式執行,所以在發出請求之後,還可以做其他的操作,Client 不會卡在那邊等 Server 的值回傳。

Server 取值時序圖

若改用同步的方式來實現,執行時序圖如下:

Server 取值時序圖(同步)

可以發現,如果採用同步的方式來取 Server 的值,假設 API 需要花費比較長的時間才會得到結果,那麼用戶端就會卡在那邊,等待 Server 的回傳值,更不用說如果等待的時間拉長,會嚴重影響使用的體驗。在 Android 上,只要主執行緒 (Main Thread) 停住五秒鐘以上,就會顯示 ANR (Application Not Response)來警告使用者。

所以當執行這些結果不是立刻取得的任務時,為了避免不會因執行太久、等待太久而導致使用者使用體驗不好,我們會使用非同步的方式來處理。

簡單來說,非同步的概念就是我請別人幫忙做事,別人做完之後再通知我。那麼這樣子就不會佔用到主執行緒,當然如果非同步執行的程式需要花費很多時間,非同步應該要可以隨時被停止,Coroutine 在這一點就做得蠻好的。

除了耗時任務以外,有些時候我們需要延遲執行我們的程式,也就是說當我們呼叫的時候這段程式碼不會立刻執行,而是等待一段時間才繼續執行,並回傳結果,

Coroutine 要解決的問題

介紹了同步以及非同步的差異,聰明的讀者你應該已經猜到了,沒錯,Coroutine 就是用來解決非同步的種種問題。

心智圖

同步與非同步的心智圖


特別感謝

Kotlin Taiwan User Group
Kotlin 讀書會


由本系列文改編的《Kotlin 小宇宙:使用 Coroutine 優雅的執行非同步任務》已經上市囉。

有興趣的讀者歡迎參考:https://coroutine.kotlin.tips/
天瓏書局


下一篇
Day2:非同步執行與 Callback 的問題
系列文
Coroutine 停看聽30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
lionlions
iT邦新手 3 級 ‧ 2023-09-14 14:14:20

大大介紹同步與非同步
寫的淺顯易懂!! 讚讚!!
小小建議
最後一張心智圖的中心 "同步/非同步"
跟拉出去的線是相反的,左邊是非同步,右邊是同步
有可能會記錯它們的特性唷

我要留言

立即登入留言