广告
返回顶部
首页 > 资讯 > 移动开发 >Kotlin挂起函数的详细介绍
  • 441
分享到

Kotlin挂起函数的详细介绍

2024-04-02 19:04:59 441人浏览 八月长安
摘要

Kotlin 协程的优势: 解决回调地狱的问题。以同步的方式完成异步任务。 示例: fun main() { runBlocking { val a = ge

Kotlin 协程的优势:

  • 解决回调地狱的问题。
  • 以同步的方式完成异步任务。

示例:

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关键字修饰的方法 就是 挂起函数。挂起函数具备挂起和恢复的能力。挂起就是将程序执行流程转移到其他线程,主线程不阻塞。挂起函数的本质是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 {

可以发现上面的Continuation 是一个带有泛型参数的Callback,这里的转换称为CPS转换,将原本的同步挂起函数转换成CallBack异步代码。


@SinceKotlin("1.3")
public interface Continuation<in T> {
    
    public val context: CoroutineContext
    
    public fun resumeWith(result: Result<T>)
}

注意:挂起函数,只能在协程中被调用,或者被其他挂起函数调用。

为什么挂起函数可以调用挂起函数,而普通函数不能调用挂起函数?

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。

挂起函数最终都是在协程中被调用,协程提供了挂起函数运行的环境。

到此这篇关于Kotlin挂起函数的详细介绍的文章就介绍到这了,更多相关Kotlin挂起函数内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Kotlin挂起函数的详细介绍

本文链接: https://www.lsjlt.com/news/167086.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Kotlin挂起函数的详细介绍
    Kotlin 协程的优势: 解决回调地狱的问题。以同步的方式完成异步任务。 示例: fun main() { runBlocking { val a = ge...
    99+
    2022-11-13
  • Kotlin扩展函数超详细介绍
    目录1.扩展函数2.infix 关键字3.扩展函数文件4.重命名扩展函数1.扩展函数 1)当我们没法接触某个类的定义,或者某个类没有用open修饰无法继承时,我们可以通过扩展函数,来...
    99+
    2022-11-13
  • Kotlin函数式编程超详细介绍
    目录1.函数式编程2.函数类别3.变换函数(transform)4.过滤函数(filter)5.合并函数(combine)1.函数式编程 我们都知道java是面向对象编程范式。在ja...
    99+
    2022-11-13
  • Kotlin作用域函数应用详细介绍
    目录1.前置知识2.使用3.源码赏析3.1 let和run3.2 also和apply3.3 repeat3.4 with4.反编译5.小结平时看博客或者学知识,学到的东西比较零散,...
    99+
    2022-11-13
  • Kotlin作用域函数使用示例详细介绍
    目录1 let2 run3 with4 apply5 also这里我们将介绍Kotlin 5个作用域函数:let,run,with,apply,also。 1 let let 可用于...
    99+
    2023-02-17
    Kotlin作用域函数 Kotlin作用域
  • JavaScript函数的详细介绍
    本篇内容主要讲解“JavaScript函数的详细介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript函数的详细介绍”吧!一、函数语法一个Jav...
    99+
    2022-10-19
  • JavaScript的function函数详细介绍
    通过函数来封装任意多条语句,而且可以在任何地方、任何时间调用执行。 而我们的JavaScript脚本语言比较特殊,相对于C语言,它的参数是不需要数据类型加持的。返回值return,...
    99+
    2022-11-12
  • Kotlin类的继承实现详细介绍
    1.在kotlin中,默认类都是封闭的closed的。如果要让某个类开放继承,必须用open关键字修饰 类中的方法默认也是关闭的。如果需要子类复写父类的方法,也必须用open修饰。 ...
    99+
    2022-11-13
  • Python 循环函数详细介绍
    目录一、循环函数1、for循环2、while循环3、中断循环二、循环设计1、range()2、enumerate()3、zip()三、循环对象1、什么是循环对象2、迭代器3、生成器4...
    99+
    2022-11-12
  • Java 函数编程详细介绍
    目录一、函数编程Lambda1、接口二、Java函数接口1、Predicate2、Consumer3、Function4、Supplier三、类型检查1、Capturing Lamb...
    99+
    2022-11-12
  • KotlinExtensionFunction扩展函数详细介绍
    目录1 什么是扩展函数(Extension Function)2 为什么使用扩展函数(Extension Function)3 如何使用扩展函数(Extension Function...
    99+
    2023-02-17
    Kotlin Extension Function Kotlin扩展函数
  • MySQL内部函数的超详细介绍
    目录字符串函数1. length(str)2. concat(str1,str1,…)3. insert(str1,n,m,str2)4. lower(str)5. upper(str)6. le...
    99+
    2022-08-08
    mysql内置函数有哪些 mysql常用内置函数 sql函数大全及举例
  • javascript中全局函数的详细介绍
    本篇内容主要讲解“javascript中全局函数的详细介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript中全局函数的详细介绍”吧! ...
    99+
    2022-10-19
  • MySQL之存储函数详细介绍
    目录1、创建存储函数2 、调用存储函数3、删除存储函数4、查看存储过程5、修改存储函数6、对比存储函数和存储过程7、练习题加强1、创建存储函数 语法格式: CREATE FUNC...
    99+
    2022-11-12
  • Python max内置函数详细介绍
    Python max内置函数 max(iterable, *[, key, default]) max(arg1, arg2, *args[, key]) Return the largest item i...
    99+
    2022-06-04
    详细介绍 函数 Python
  • 详细介绍Java函数式接口
    目录Java—函数式接口1.自定义函数式接口1.1概述1.2格式1.3@FunctionalInterface注解1.4自定义函数式接口2.函数式编程2.1Lambda的延迟执行2....
    99+
    2022-11-12
  • KotlinSuspend挂起函数的使用详解
    目录总结本质何时使用消除回调一些例子总结 挂起(suspend)函数是所有协程的核心。 挂起函数可以执行长时间运行的操作并等待它完成而不会阻塞主线程。 挂起函数的语法与常规函数的语法...
    99+
    2023-02-17
    Kotlin Suspend挂起函数 Kotlin Suspend Kotlin挂起函数
  • 详细介绍PHP函数和方法的区别
    随着互联网技术的发展,PHP已经成为了非常流行的开发语言之一。身为一个PHP开发者,了解PHP函数和方法的区别是非常重要的,因为它们在编写代码的时候都是必不可少的。在本文中,我们将详细介绍PHP函数和方法的区别。PHP函数是一段可重复使用的...
    99+
    2023-05-14
    php php函数
  • 详细介绍Android中回调函数机制
    提示:在阅读本文章之前,请确保您对Touch事件的分发机制有一定的了解 在Android的学习过程中经常会听到或者见到“回调”这个词,那么什么是回调呢?所谓的回调函数就是:在A...
    99+
    2022-06-06
    回调 函数 回调函数 Android
  • Android 自定义View的构造函数详细介绍
     Android自定义View的构造函数 自定义View是Android中一个常见的需求,每个自定义的View都需要实现三个基本的构造函数,而这三个构造函数又有两种...
    99+
    2022-06-06
    view 函数 自定义view 构造函数 Android
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作