通過async與await實現高效並發


withTimeoutOrNull:

 在上一次https://www.cnblogs.com/webor2006/p/12010388.html中對於協程的超時機制進行了一個學習,上次用的是withTimeout()函數,還有一個重載這次來看一下:

先來說一下它產生的背景,我們知道在上一次用withTimeout()時如果超時了會拋出一個異常:

該異常是CancellationException的子類,當該異常拋出時,我們並未在控制台上看到整個異常堆棧信息,這是因為在取消的協程當中,CancellationException被認為是一種協程完成的正常原因而已。不過,我們在該示例中,是在main函數中使用了withTimeout函數調用,既然CancellationException僅僅只是個異常而已,所有的資源也都會以通常的方式來關閉,那么我們就可以將相關代碼放到一個try...catch塊中;此外,Kotlin還提供了另外一個更加友好的函數調用:withTimeoutOrNull;從功能角度來着,它非常類似於withTimeout,不過當超時發生時,它並不會拋出CancellationException異常,而是會直接返回null。

對於withTimeout函數調用來說,如果將其放置到try...catch塊中,那么調用形式就是下面這樣:

但是!!如果咱們采用withTimeoutOrNull來使用的話,其形式就會變成這樣:

那如果改為正常執行呢?

 

至此對於協程的超時機制就學習完了。

async與await:

接下來學習一個全新的知識點,關於它貌似前陣在學習小程序的開發中也看到過,當時看着也是感覺挺陌生的一個寫法,不過當時是在JS中的代碼,這里是在Kotlin語言中,那接下來好好學學它,也有助於微信開發的這塊用法的理解,下面先從一個掛起函數的組合使用開始:

接下來則將2個掛起函數的值進行累加並打印,而且還打印一下調用這倆掛起函數的消耗總時間,這里有個小細節說明一下:說到函數的執行時間的打印可能通常的做法是這樣:

但是Kotlin為咱們提供了一個這種功能的現有函數,不用咱們自己來手動寫了,如下:

這個程序比較好理解,也很自然,這里來分析一下這種傳統寫法的弊端:

此時,async與await的使用場景就出來了,下面先對其理論進行了解:

從概念上來說,async就像是launch一樣,它會開啟一個單獨的協程,這個協程是個輕量級線程,可以與其他協程並發工作。區別在於,launch會返回一個Job,但是Job並不會持有任何結果值,而async會返回一個Deferred,這是一個輕量級的非阻塞的future,它代表一個promise,可以在稍后提供一個結果值。

可以通過在一個deferred值上調用.await()方法來獲取最終的結果值,Deferred也是個Job,因此可以在需要時對其進行取消。

好,先來看一下Deferred這個跟Job是啥關系:

所以說Deferred就是一個Job,好,下面咱們來改造一下程序,看是否能縮短執行時間:

其中可以看到async是一個擴展函數:

而await()是Deferred中定義的,如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM