Coroutine Join 有什么作用?
What does a Coroutine Join do?
例如我有以下代码:
scope.launch {
val job = launch {
doSomethingHere()
}
job.join()
callOnlyWhenJobAboveIsDone()
}
Job.join()
在文档中是这样的状态:
Suspends coroutine until this job is complete. This invocation resumes normally (without exception) when the job is complete for any reason and the Job of the invoking coroutine is still active. This function also starts the corresponding coroutine if the Job was still in new state.
如果我理解正确,因为 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()
的有效用例吗?
Kotlin 的 Job.join()
是 Java 的 Thread.join()
的非阻塞等效项。
所以你的假设是正确的:job.join()
的要点是在执行当前协程的其余部分之前等待接收器job
完成。
然而,它并没有阻塞调用 join()
的线程(就像 Java 的 Thread.join()
会做的那样),它只是暂停协程调用 join()
,留下当前线程在此期间可以自由地做任何它想做的事情(比如执行另一个协程)。
That is, the method callOnlyWhenJobAboveIsDone() will only be called when doSomethingHere() is finished. Is that correct?
是的。
Can anyone explain further the use case for job.join()?
在你的情况下实际上不需要另一份工作,你可以写:
scope.launch {
doSomethingHere()
callOnlyWhenJobAboveIsDone()
}
这将做完全相同的事情,所以它并不是真正的工作用例。现在还有其他情况.join()
真的有用。
- 您想 运行(启动)多个并行的异步操作,并等待它们全部完成:
someData
.map { Some.asyncAction(it) } // start in parallel
.forEach { it.join() } // wait for all of them
- 您必须跟踪异步状态,例如更新:
var update = Job()
fun doUpdate() {
update.cancel() // don't update twice at the same time
update = launch {
someAsyncCode()
}
}
现在要确保最后一次更新已经完成,例如如果你想使用一些更新的数据,你可以:
update.join()
任何地方,你也可以
update.cancel()
如果你愿意的话。
launch {}
真正有用的是它不仅returns一个Job,而且还把Job附加到CoroutineScope。通过它,您可以跟踪应用程序中发生的每个异步操作。例如,在您的 UI 中,您可以让每个元素扩展 CoroutineScope,然后如果元素离开渲染区域,您可以取消作用域,其中的所有更新/动画都将停止。
例如我有以下代码:
scope.launch {
val job = launch {
doSomethingHere()
}
job.join()
callOnlyWhenJobAboveIsDone()
}
Job.join()
在文档中是这样的状态:
Suspends coroutine until this job is complete. This invocation resumes normally (without exception) when the job is complete for any reason and the Job of the invoking coroutine is still active. This function also starts the corresponding coroutine if the Job was still in new state.
如果我理解正确,因为 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()
的有效用例吗?
Kotlin 的 Job.join()
是 Java 的 Thread.join()
的非阻塞等效项。
所以你的假设是正确的:job.join()
的要点是在执行当前协程的其余部分之前等待接收器job
完成。
然而,它并没有阻塞调用 join()
的线程(就像 Java 的 Thread.join()
会做的那样),它只是暂停协程调用 join()
,留下当前线程在此期间可以自由地做任何它想做的事情(比如执行另一个协程)。
That is, the method callOnlyWhenJobAboveIsDone() will only be called when doSomethingHere() is finished. Is that correct?
是的。
Can anyone explain further the use case for job.join()?
在你的情况下实际上不需要另一份工作,你可以写:
scope.launch {
doSomethingHere()
callOnlyWhenJobAboveIsDone()
}
这将做完全相同的事情,所以它并不是真正的工作用例。现在还有其他情况.join()
真的有用。
- 您想 运行(启动)多个并行的异步操作,并等待它们全部完成:
someData
.map { Some.asyncAction(it) } // start in parallel
.forEach { it.join() } // wait for all of them
- 您必须跟踪异步状态,例如更新:
var update = Job()
fun doUpdate() {
update.cancel() // don't update twice at the same time
update = launch {
someAsyncCode()
}
}
现在要确保最后一次更新已经完成,例如如果你想使用一些更新的数据,你可以:
update.join()
任何地方,你也可以
update.cancel()
如果你愿意的话。
launch {}
真正有用的是它不仅returns一个Job,而且还把Job附加到CoroutineScope。通过它,您可以跟踪应用程序中发生的每个异步操作。例如,在您的 UI 中,您可以让每个元素扩展 CoroutineScope,然后如果元素离开渲染区域,您可以取消作用域,其中的所有更新/动画都将停止。