协程联接有什么作用?

时间:2019-01-03 10:36:59

标签: kotlin kotlinx.coroutines

例如,我有以下代码:

scope.launch {
    val job = launch {
        doSomethingHere()
    }
    job.join()

    callOnlyWhenJobAboveIsDone()
}

Job.join()在文档中的状态如下:

  

暂停协程,直到此作业完成。当作业由于某种原因完成并且调用协程的作业仍处于活动状态时,此调用将正常恢复(无例外)。如果作业仍处于新状态,则此功能还会启动相应的协程。

如果我正确理解它,由于join()会暂停协程直到完成,因此上面的代码将完全按照其要求执行。也就是说,仅在callOnlyWhenJobAboveIsDone()完成时才调用方法doSomethingHere()。正确吗?

有人可以进一步解释job.join()的用例吗?预先感谢。

进一步解释我的用例:

val storeJobs = ArrayList<Job>()

fun callThisFunctionMultipleTimes() {
    scope.launch {
        val job = launch {
            doSomethingHere()
        }
        storeJobs.add(job) 
        job.join()

        callOnlyWhenJobAboveIsDone()
    }
}

fun callOnlyWhenJobAboveIsDone() {
    // Check if there is still an active job 
    // by iterating through the storedJobs
    // and checking if any is active
    // if no job is active do some other things
}

这是job.join()的有效用例吗?

2 个答案:

答案 0 :(得分:1)

Kotlin的Job.join()是Java的Thread.join()的非阻塞等效项。

因此,您的假设是正确的:job.join()的重点是在执行其余的当前协程之前,等待接收者job的完成。

但是,它并没有阻塞调用join()的线程(就像Java的Thread.join()那样),而是简单地挂起了协程调用join(),使当前线程可以自由地做自己喜欢的事(例如执行另一个协程)。

答案 1 :(得分:1)

  

也就是说,仅在doSomethingHere()完成时才调用方法callOnlyWhenJobAboveIsDone()。正确吗?

是的

  

有人可以进一步解释job.join()的用例吗?

在您的情况下,实际上不需要其他工作,您可以写:

scope.launch {
    doSomethingHere()
    callOnlyWhenJobAboveIsDone()
}

这将做完全相同的事情,因此它实际上不是Job的用例。现在还有其他情况,.join()确实有用。

1)您要并行运行(启动)多个异步操作,并等待它们全部完成:

 someData
   .map { Some.asyncAction(it) } // start in parallel
   .forEach { it.join() } // wait for all of them

2)您必须跟踪异步状态,例如更新:

var update = Job()

fun doUpdate() {
   update.cancel() // don't update twice at the same time
   update = launch {
     someAsyncCode()
   }
}

现在要确保上一次更新已完成,例如,如果您要使用一些更新的数据,则可以:

 update.join()

在任何地方,您也可以

 update.cancel()

如果需要的话。

launch {}真正有用的是它不仅返回Job,而且将Job附加到CoroutineScope。通过它,您可以跟踪应用程序内部发生的每个异步操作。例如,在您的UI中,可以使每个Element扩展CoroutineScope,然后可以在Element离开渲染区域时取消范围,并且其中的所有更新/动画都将停止。