协程 Kotlin 中 Job 和 Deferred 的区别
Difference between Job and Deferred in Coroutines Kotlin
我是协程的新手,我理解 launch
和 async
但仍然令人困惑的部分是 Deferred
。 Deferred
是什么? Job
和 Deferred
之间的差异。清晰的解释和示例更有帮助。提前致谢。
所以 job
是一种表示协程执行的对象,与 structured concurrency 相关,例如您可以取消一个作业,这个作业的所有子作业也将被取消。
来自 docs:
Job is a cancellable thing with a life-cycle that culminates in its completion.
Deferred
是 Java 中 Future
的某种模拟:封装了一个操作,该操作将在初始化后的某个时间点完成。但也与 Kotlin 中的协程有关。
来自文档:
Deferred value is a non-blocking cancellable future — it is a Job that has a result.
所以,Deferred
是一个 Job
,结果是:
A deferred
value is a Job
. A job
in the coroutineContext
of async
builder represents the coroutine itself.
一个例子:
someScope.launch {
val userJob: Deferred<User> = async(IO) { repository.getUser(id) }
//some operations, while user is being retrieved
val user = userJob.await() //here coroutine will be suspended for a while, and the method `await` is available only from `Deferred` interface
//do the job with retrieved user
}
此外,可以使用现有范围构建此 async
请求,但这是另一个问题。
在基本层面上,Deferred
是一个未来。它使一个协程可以等待另一个协程产生的结果,并暂停自身直到准备就绪。调用 async
是获得 Deferred
.
的一种方法,但到目前为止并不是唯一的方法
但是,我认为您的问题更多是关于基础知识:何时使用 launch
,何时使用 async-await
。这是一个重要的教训:你可能不需要异步。人们倾向于使用它是因为关键字 async
和 await
在其他语言中很熟悉,但在 Kotlin 中,async
并不是实现非阻塞调用的通用工具。
这里有一个关于如何将阻塞调用变成暂停、非阻塞调用的基本方法:
uiScope.launch {
val ioResult = withContext(Dispatchers.IO) { blockingIOCall() }
... just use the result, you're on the GUI thread here.
}
我是协程的新手,我理解 launch
和 async
但仍然令人困惑的部分是 Deferred
。 Deferred
是什么? Job
和 Deferred
之间的差异。清晰的解释和示例更有帮助。提前致谢。
所以 job
是一种表示协程执行的对象,与 structured concurrency 相关,例如您可以取消一个作业,这个作业的所有子作业也将被取消。
来自 docs:
Job is a cancellable thing with a life-cycle that culminates in its completion.
Deferred
是 Java 中 Future
的某种模拟:封装了一个操作,该操作将在初始化后的某个时间点完成。但也与 Kotlin 中的协程有关。
来自文档:
Deferred value is a non-blocking cancellable future — it is a Job that has a result.
所以,Deferred
是一个 Job
,结果是:
A
deferred
value is aJob
. Ajob
in thecoroutineContext
ofasync
builder represents the coroutine itself.
一个例子:
someScope.launch {
val userJob: Deferred<User> = async(IO) { repository.getUser(id) }
//some operations, while user is being retrieved
val user = userJob.await() //here coroutine will be suspended for a while, and the method `await` is available only from `Deferred` interface
//do the job with retrieved user
}
此外,可以使用现有范围构建此 async
请求,但这是另一个问题。
在基本层面上,Deferred
是一个未来。它使一个协程可以等待另一个协程产生的结果,并暂停自身直到准备就绪。调用 async
是获得 Deferred
.
但是,我认为您的问题更多是关于基础知识:何时使用 launch
,何时使用 async-await
。这是一个重要的教训:你可能不需要异步。人们倾向于使用它是因为关键字 async
和 await
在其他语言中很熟悉,但在 Kotlin 中,async
并不是实现非阻塞调用的通用工具。
这里有一个关于如何将阻塞调用变成暂停、非阻塞调用的基本方法:
uiScope.launch {
val ioResult = withContext(Dispatchers.IO) { blockingIOCall() }
... just use the result, you're on the GUI thread here.
}