欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Kotlin掛起函數的詳細介紹

 更新時間:2022年09月07日 17:11:45   作者:且聽真言  
掛起函數用狀態(tài)機以掛起點將協(xié)程的運算邏輯拆分成不同的片段,每次執(zhí)行協(xié)程運行不同的邏輯片段,由此可以知道協(xié)程是運行在線程中的,線程的并發(fā)處理方式也可以用在協(xié)程上

Kotlin 協(xié)程的優(yōu)勢:

  • 解決回調地獄的問題。
  • 以同步的方式完成異步任務。

示例:

fun main() {
    runBlocking {
        val a = getA()
        println(a)
        val b = getB(a)
        println(b)
        val c = getC(b)
        println(c)
    }
}
suspend fun getA(): String {
    withContext(Dispatchers.IO) {
        delay(2000L)
    }
    return "A content"
}
suspend fun getB(a: String): String {
    withContext(Dispatchers.IO) {
        delay(2000L)
    }
    return "$a B content"
}
suspend fun getC(b: String): String {
    withContext(Dispatchers.IO) {
        delay(2000L)
    }
    return "$b C content"
}

輸出
A content
A content B content
A content B content C content

suspend關鍵字修飾的方法 就是 掛起函數。掛起函數具備掛起和恢復的能力。掛起就是將程序執(zhí)行流程轉移到其他線程,主線程不阻塞。掛起函數的本質是Callback。

Kotlin編譯器檢測到suspend關鍵字修飾的函數,會將掛起函數轉換成帶有CallBack的函數。

suspend fun getA(): String {
    withContext(Dispatchers.IO) {
        delay(5000L)
        println("now in A process:" + Thread.currentThread())
    }
    /**
     * 這里的代碼涉及掛起函數中的操作。
     */
    println("finish A process:" + Thread.currentThread())
    return "A content"
}

將上述Kotlin代碼轉換成java代碼。

 @Nullable
   public static final Object getA(@NotNull Continuation var0) {
      Object $continuation;
      label20: {
         if (var0 instanceof <undefinedtype>) {
            $continuation = (<undefinedtype>)var0;
            if ((((<undefinedtype>)$continuation).label & Integer.MIN_VALUE) != 0) {
               ((<undefinedtype>)$continuation).label -= Integer.MIN_VALUE;
               break label20;
            }
         }
         $continuation = new ContinuationImpl(var0) {
            // $FF: synthetic field
            Object result;
            int label;
 
            @Nullable
            public final Object invokeSuspend(@NotNull Object $result) {
               this.result = $result;
               this.label |= Integer.MIN_VALUE;
               return TestCoroutinue2Kt.getA(this);
            }
         };
      }
      Object $result = ((<undefinedtype>)$continuation).result;
      Object var4 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
      switch(((<undefinedtype>)$continuation).label) {
      case 0:
         ResultKt.throwOnFailure($result);
         CoroutineContext var10000 = (CoroutineContext)Dispatchers.getIO();
         Function2 var10001 = (Function2)(new Function2((Continuation)null) {
            int label;
            @Nullable
            public final Object invokeSuspend(@NotNull Object $result) {
               Object var3 = IntrinsicsKt.getCOROUTINE_SUSPENDED();
               switch(this.label) {
               case 0:
                  ResultKt.throwOnFailure($result);
                  this.label = 1;
                  if (DelayKt.delay(5000L, this) == var3) {
                     return var3;
                  }
                  break;
               case 1:
                  ResultKt.throwOnFailure($result);
                  break;
               default:
                  throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
               }
               String var2 = "now in A process:" + Thread.currentThread();
               System.out.println(var2);
               return Unit.INSTANCE;
            }
            @NotNull
            public final Continuation create(@Nullable Object value, @NotNull Continuation completion) {
               Intrinsics.checkNotNullParameter(completion, "completion");
               Function2 var3 = new <anonymous constructor>(completion);
               return var3;
            }
            public final Object invoke(Object var1, Object var2) {
               return ((<undefinedtype>)this.create(var1, (Continuation)var2)).invokeSuspend(Unit.INSTANCE);
            }
         });
         ((<undefinedtype>)$continuation).label = 1;
         if (BuildersKt.withContext(var10000, var10001, (Continuation)$continuation) == var4) {
            return var4;
         }
         break;
      case 1:
         ResultKt.throwOnFailure($result);
         break;
      default:
         throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
      }
      String var1 = "finish A process:" + Thread.currentThread();
      System.out.println(var1);
      return "A content";
   }

注意:runBlocking 的第二個參數 也是 傳入一個 suspend修飾的函數 即掛起函數。

public actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T {

可以發(fā)現(xiàn)上面的Continuation 是一個帶有泛型參數的Callback,這里的轉換稱為CPS轉換,將原本的同步掛起函數轉換成CallBack異步代碼。

/**
 * Interface representing a continuation after a suspension point that returns a value of type `T`.
 */
@SinceKotlin("1.3")
public interface Continuation<in T> {
    /**
     * The context of the coroutine that corresponds to this continuation.
     */
    public val context: CoroutineContext
    /**
     * Resumes the execution of the corresponding coroutine passing a successful or failed [result] as the
     * return value of the last suspension point.
     */
    public fun resumeWith(result: Result<T>)
}

注意:掛起函數,只能在協(xié)程中被調用,或者被其他掛起函數調用。

為什么掛起函數可以調用掛起函數,而普通函數不能調用掛起函數?

fun main() {
    doA() //這里會報錯
}
suspend fun doA() {
}
 public static final void main() {
   }
   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }
 @Nullable
   public static final Object doA(@NotNull Continuation $completion) {
      return Unit.INSTANCE;
   }

被調用的掛起函數需要傳入一個Continuation, 沒有被suspend修飾的函數是沒有Continuation參數的,所以沒法在普通函數中調用掛起函數,普通函數沒有Continuation。

掛起函數最終都是在協(xié)程中被調用,協(xié)程提供了掛起函數運行的環(huán)境。

到此這篇關于Kotlin掛起函數的詳細介紹的文章就介紹到這了,更多相關Kotlin掛起函數內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Android提高之BroadcastReceiver實例詳解

    Android提高之BroadcastReceiver實例詳解

    這篇文章主要介紹了Android的BroadcastReceiver用法,在Android的項目開發(fā)中是比較實用的功能,需要的朋友可以參考下
    2014-08-08
  • 如何在原有Android項目中快速集成React Native詳解

    如何在原有Android項目中快速集成React Native詳解

    創(chuàng)建一個React Native項目并寫一個純的 React Native 應用可以參考官方指南。下面這篇文章主要給大家介紹了關于如何在原有Android項目中快速集成React Native的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。
    2017-12-12
  • Flutter實現(xiàn)底部菜單導航

    Flutter實現(xiàn)底部菜單導航

    這篇文章主要為大家詳細介紹了Flutter實現(xiàn)底部菜單導航,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • Android SeekBar 自定義thumb旋轉動畫效果

    Android SeekBar 自定義thumb旋轉動畫效果

    某些音樂播放或者視頻播放的界面上,資源還在加載時,進度條的原點(thumb)會顯示一個轉圈的效果。這篇文章主要介紹了Android SeekBar 自定義thumb thumb旋轉動畫效果,需要的朋友可以參考下
    2021-11-11
  • 詳解Android業(yè)務組件化之URL Schema使用

    詳解Android業(yè)務組件化之URL Schema使用

    這篇文章主要為大家詳細介紹了Android業(yè)務組件化之URL Schema使用,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Android設置圖片圓角的方法

    Android設置圖片圓角的方法

    這篇文章主要為大家詳細介紹了Android設置圖片圓角的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • android仿支付寶、微信密碼輸入框效果

    android仿支付寶、微信密碼輸入框效果

    這篇文章主要為大家詳細介紹了android仿支付寶、微信密碼輸入框效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Android 獲取手機信息實例詳解

    Android 獲取手機信息實例詳解

    這篇文章主要介紹了Android 獲取手機信息實例詳解的相關資料,這里附有實例代碼及實現(xiàn)效果圖,需要的朋友可以參考下
    2017-01-01
  • Android中volley封裝實踐記錄(二)

    Android中volley封裝實踐記錄(二)

    這篇文章主要給大家介紹了關于Android中volley封裝的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-02-02
  • Android開發(fā)實現(xiàn)ImageView加載攝像頭拍攝的大圖功能

    Android開發(fā)實現(xiàn)ImageView加載攝像頭拍攝的大圖功能

    這篇文章主要介紹了Android開發(fā)實現(xiàn)ImageView加載攝像頭拍攝的大圖功能,涉及Android基于ImageView的攝像頭拍攝圖片加載、保存及權限控制等相關操作技巧,需要的朋友可以參考下
    2017-11-11

最新評論