iT邦幫忙

2021 iThome 鐵人賽

DAY 1
0
Software Development

Coroutine 停看聽系列 第 1

Day 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 讀書會


下一篇
Day2:非同步執行與 Callback 的問題
系列文
Coroutine 停看聽30

尚未有邦友留言

立即登入留言