6.協(xié)程的掛起

掛起函數(shù)的作用以及使用場景:
掛起函數(shù)會讓協(xié)程從正在執(zhí)行它的線程上脫離,并在掛起函數(shù)執(zhí)行結(jié)束恢復(fù)到原線程,實現(xiàn)非阻塞式掛起。
可用于耗時的函數(shù)比如聯(lián)網(wǎng)獲取數(shù)據(jù),數(shù)據(jù)庫讀寫,文件io等
1.標(biāo)準(zhǔn)掛起函數(shù)應(yīng)該定義線程切換,取消機制,結(jié)果返回三個部分
retrofit2.7.1里面部分源碼KotlinExtensions.class

@JvmName("awaitNullable")
suspend fun <T : Any> Call<T?>.await(): T? {
  return suspendCancellableCoroutine { continuation ->
    continuation.invokeOnCancellation {
      cancel()
    }
    enqueue(object : Callback<T?> {
      override fun onResponse(call: Call<T?>, response: Response<T?>) {
        if (response.isSuccessful) {
          continuation.resume(response.body())
        } else {
          continuation.resumeWithException(HttpException(response))
        }
      }

      override fun onFailure(call: Call<T?>, t: Throwable) {
        continuation.resumeWithException(t)
      }
    })
  }
}

2.如何自定義掛起函數(shù)
僅僅依靠suspend修飾符是改變不了線程的

suspend fun getUser():String{
    log("getUser")
    return ""
}
suspend fun main(){
    getUser()
}

打?。?/p>

16:07:05:167 [main,1] getUser

示例1 只有返回值跟切換線程

suspend fun getUserInIo()= withContext(Dispatchers.IO){
    "hhahah"
}
suspend fun main(){
    GlobalScope.launch {
        val userInIo = getUserInIo()
        log(userInIo)
    }.join()
}

打印:

16:23:50:267 [DefaultDispatcher-worker-3,14] hhahah

示例 不做線程切換,依靠協(xié)程做切換

suspend fun getUser1()= suspendCoroutine<String> {
    //直接使用當(dāng)前協(xié)程所在的線程,不做切換
    it.resume("hhahahah")
}
suspend fun main(){
    val user1 = getUser1()
    log(user1)
    GlobalScope.launch {
        log(1)
        val user11 = getUser1()
        log(user1)
        withContext(Dispatchers.IO){
            val user11 = getUser1()
            log(user1)
        }
    }.join()
}

示例
既做線程切換,又有取消

suspend fun getUserInFile()= suspendCancellableCoroutine<Int> {
    var threadStop=true
    it.invokeOnCancellation {
        //如果沒有這個,那么掛起函數(shù)是無法取消的
        threadStop=false
    }
    thread (name = "hahaha"){
        //模擬耗時操作
        try {
            var i=0;
            while (threadStop&&i<1000){
                Thread.sleep(100)
                i++
                log(i)
            }
            it.resume(i)
        }catch (e: Exception){
            it.resumeWithException(e)
        }
    }
}
suspend fun main(){
    val launch = GlobalScope.launch{
        log("start")
        val userInFile = getUserInFile()
        log(userInFile)
    }
    delay(1000)
    launch.cancel()
    delay(1000)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容