在Kotlin 中如何轻松愉快的处理异步操作

起步

kotlin通过协程来实现异步操作,关于协程的一些基本概念可以参考这里Kotlin中线程的代替者——协程,究竟有什么好?.

kotlin在它的标准库中仅仅提供了最小化的底层API的支持。像 asyncawait 既不是Kotlin的关键字,又没有被包括在标准库中。

对于一般的开发者,或是刚入门的的人来说仅仅通过标准库提供的那些东西,要想使用其协程来是十分困难的。

幸运的是,我们不要从头写起,Kotlin官方已经为我们提供了轮子。kotlin.coroutines,这是一个十分丰富的库,它包含了大量的高层的开启协程的基本元素,包括前面提到的 asyncawait

这个库是没有包含在标准库中,要想使用它必须导入相应的依赖。

Maven

<repository>
    <id>central</id>
    <url>http://jcenter.bintray.com</url>
</repository>
<dependency>
    <groupId>org.jetbrains.kotlinx</groupId>
    <artifactId>kotlinx-coroutines-core</artifactId>
    <version>0.18</version>
</dependency>

kotlin的版本需要1.1.4以上的版本(包括1.1.4)

repositories {
    jcenter()
}
compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.18'
buildscript {
    ext.kotlin_version = '1.1.4'
}

基础

接下来,开始编写你的第一段协程代码

fun main(args: Array<String>) {
    launch(CommonPool) { // 在一个公共线程池中创建一个协程
        delay(1000L) // 非阻塞的延迟一秒(默认单位是毫秒)
        println("World!") // 在延迟后进行打印
    }
    println("Hello,") // 主线程在协程延时后,不受影响,继续执行
    Thread.sleep(2000L) // 阻塞主线程2秒钟,保持JVM存活
}

输出结果:

Hello,
World!

在这里协程通过名为launch的协程建造器进行启动。你可以把launch(CommonPool){…}换成 thread{…};delay() 换成 Thread.sleep()。
但是如果只是把launch换了,然后依旧使用delay()会产生怎样的结果呢?编译器会告诉你,发生了下面这样的错误:

Suspend functions are only allowed to be called from a coroutine or another suspend function

大意就是,挂起函数只允许在协程中或是另一个挂起函数中调用。而delay() 恰巧就是一个挂起函数,因此产生了这样的错误。

上个例子混合了阻塞和非阻塞的代码。那么我么怎么得到一个只有非阻塞操作的世界呢?这里我们就需要用到 run Blocking

fun main(args: Array<String>) = runBlocking<Unit> { // 开启主协程
    launch(CommonPool) { // 在公共线程池中创建一个协程
        delay(1000L)
        println("World!")
    }
    println("Hello,") // 主协程在子协程延迟时继续执行
    delay(2000L) // 两秒钟的非阻塞延时,保持JVM存活
}

假如主协程在子协程还没有执行之前就已经结束了,那么子协程也会随之结束。可是我们并不像让子协程结束,改怎么办呢?可以使用join()让主协程等待子协程执行完成。

fun main(args: Array<String>) = runBlocking<Unit> {
    val job = launch(CommonPool) { // 创建一个协程并维持一个指向它任务的引用
        delay(1000L)
        println("World!")
    }
    println("Hello,")
    job.join() // 持续等待,直到子协程执行完成
}

接下来讲一下,这一次的最后一点内容:创建你的第一个挂起函数。

fun main(args: Array<String>) = runBlocking<Unit> {
    val job = launch(CommonPool) { doWorld() }
    println("Hello,")
    job.join()
}

// 这是你的第一个挂起函数
suspend fun doWorld() {
    delay(1000L)
    println("World!")
}

使用挂起函数有两点需要注意的地方
1. 声明挂起函数需要添加 suspend 修饰符
2. 挂起函数只能在协程中或是其它的挂起函数中使用。

更多关于Kotlin的文章,欢迎关注Kotlin学习网

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值