web-dev-qa-db-ja.com

コルーチンKotlinのジョブと据え置きの違い

コルーチンは初めてですが、起動と非同期を理解していますが、混乱する部分は延期されます。延期とは何ですか?明確な説明と例がより役立ちます。前もって感謝します

16
Magesh Pandian

したがって、jobはコルーチンの実行を表すオブジェクトの一種であり、 structured concurrency に関連しています。ジョブをキャンセルできます。このジョブのすべての子もキャンセルされます。

docs から:

Jobはキャンセル可能なものであり、ライフサイクルが完了して終了します。

Deferredは、JavaのFutureの一種の類似物です。初期化後のある時点で終了する操作をカプセル化します。しかし、コトリンのコルーチンにも関連しています。

ドキュメントから:

延期された値は、非ブロッキングのキャンセル可能な未来です。結果を持つのはジョブです。

したがって、Deferredは結果を持つJobです。

deferred値はJobです。 job of coroutineContextビルダーのasyncは、コルーチン自体を表します。

例:

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リクエストを既存のスコープで構成することも可能ですが、それは別の問題です。

12
Andrey Ilyunin

基本的なレベルでは、Deferredは未来です。これにより、1つのコルーチンが別のコルーチンによって生成される結果を待機し、準備ができるまでそれ自体を一時停止できます。 asyncを呼び出すのは1つの方法ですが、Deferredを取得する方法はこれだけではありません。

しかし、あなたの質問は基本についてのより多くだと思います:launchをいつ使うべきか、async-awaitをいつ使うべきか。ここに重要なレッスンがあります:おそらく非同期は必要ありません。キーワードasyncawaitは他の言語でよく知られているため、人々はそれを使用する傾向がありますが、Kotlinではasyncは非ブロッキング呼び出しを実現する汎用ツールではありません。

以下は、ブロッキング呼び出しを一時停止、非ブロッキング呼び出しに変換する方法の基本的なレシピです。

uiScope.launch {
    val ioResult = withContext(Dispatchers.IO) { blockingIOCall() }
    ... just use the result, you're on the GUI thread here.
}
6
Marko Topolnik