day15 job的骚操作

今天再讲些简单的,顺便复习复习前面的东西,之後又有几天比较硬的内容
我们每次创建coroutine都汇回传一个job,而我们除了cancel,还可以用他的其他方法

join

join会等待一个job结束

val scope = launch {
    delay(1000)
    Timber.d("scope")
    delay(1000)
    Timber.d("scope")
}

launch (Dispatchers.IO){
    Timber.d("io")
}
/**
 * io
 * scope
 * scope
 * */

那今天我改成这样

val scope = launch {
    delay(1000)
    Timber.d("scope")
    delay(1000)
    Timber.d("scope")
}
scope.join()
launch (Dispatchers.IO){
    Timber.d("io")
}
/**
 * scope
 * scope
 * io
 * */

可以看到他会等待该scope任务结束在执行之後的程序

joinAll
既然已经了解了join,joinAll的概念也就呼之欲出了,等待复数个job工作结束

lifecycleScope.launch {

    val scope = launch {
        delay(1000)
        Timber.d("scope")
        delay(1000)
        Timber.d("scope")
    }
    val scope2 = launch {
        delay(1000)
        Timber.d("scope2")
        delay(1000)
        Timber.d("scope2")
    }
    joinAll(scope, scope2)
    launch (Dispatchers.IO){
        Timber.d("io")
    }
}

/**
 * scope
 * scope2
 * scope
 * scope2
 * io
 * */

find childs

fun checkJob() {
    val jjob = viewModelScope.launch {

        launch {
            delay(1000L)
            Timber.d("in launch $this")
        }
        launch {
            delay(1000L)
            Timber.d("in launch $this")
        }
    }
    jjob.children.forEach {
        Timber.d("find child $it")
    }
}

childeren可以找到该job的childrens,作为Sequence< Job>回传,但无法找到child的child,另一方面,能找到的child,仅限以创建且还没complete的job

以这个例子而言,如果把delay拿掉,launch作为fire and forget的coroutine,就不会被jjob.children.forEach印出

lazy start

val jjob = viewModelScope.launch (start = CoroutineStart.LAZY){

    launch {
        delay(1000L)
        Timber.d("in launch $this")
    }
    launch {
        delay(1000L)
        Timber.d("in launch $this")
    }
}
Timber.d("first log")
jjob.start()

开始coroutine这篇里面,就有用到lazy start,不只是CoroutineScope可以用,以物件导向来理解的话,lifecycleScope和viewModelScope,可以当作继承CoroutineScope的子类,所以用法没甚麽区别,只有让我们更方便而已

而start会遇到两种情况,如果job还没开始,就启动coroutine,并返回true,否则返回false

isActive和ensureActive

val jjob = viewModelScope.launch {

    while (isActive){
        Timber.d("coffee")
    }
    while (true){
        ensureActive()
        Timber.d("milk")
    }
}
jjob.cancel()

两个用途差不多,反正如果不检查直接用while(true)会无法取消,详情看取消

job.cancelAndJoin()
cancels the job and waits for its completion
我们在取消篇讲过,job取消不是直接取消,是会先进入canceling state,那join是等待coroutine工作完成,cancelAndJoin,就是两个一起用

//没骗你,这是source code
public suspend fun Job.cancelAndJoin() {
    cancel()
    return join()
}

join和await比较

这样看来,await和join都有等待的意思,但他们差异却很大

launch回传的job/ join,是一组用法,他们在遇到Exception的时候,会直接向上传递,并且他们是阻塞式的

async/await是另一组用法,遇到Exception的时候会将存放在Deferred< T>里面,并期待开发者呼叫await,此外其非阻塞式的用法可以并发呼叫


<<:  [Day 17] Facial Recognition - siamese networks: 只是一个开始

>>:  Day16_HTML语法13

Day 14: Draft

GOOGLE公云使用案例 大纲 Introduction(Global view) How to c...

企划实现(21)

接续上篇继续提到关於有限公司以及股份有限公司的差别。 有限公司以及股份有限公司除了制度会有差别外,责...

[Day01] 前言

身为一个商业设计的转职者,从懵懂到认识 HTML 与 CSS 之後,接着来到进入 JavaScrip...

Swift纯Code之旅 Day20. 「ViewController好乱(2) - MVC画面分离」

前言 昨天已经将要用来实作MVC分离的范例完成了,那今天就马上来实作MVC分离吧! 实作 首先先创一...

【Android-Notification(通知)】 介绍+实作练习

前言: 通常会和Broadcast(广播)一起使用,在app status条显示的资料, 可以在Ap...