Entonces, por ejemplo, tengo el siguiente código:
scope.launch { val job = launch { doSomethingHere() } job.join() callOnlyWhenJobAboveIsDone() } Job.join() se indica como tal en la documentación:
Suspende la rutina hasta que se complete este trabajo. Esta invocación se reanuda normalmente (sin excepción) cuando el trabajo se completa por cualquier motivo y el trabajo de la corrutina que invoca aún está activo. Esta función también inicia la rutina correspondiente si el trabajo todavía estaba en un estado nuevo.
Si lo entiendo correctamente, dado que join() suspende la rutina hasta que se completa, entonces mi código anterior hará exactamente lo que quiere. Es decir, el método callOnlyWhenJobAboveIsDone() solo se llamará cuando finalice doSomethingHere( doSomethingHere() . ¿Es eso correcto?
¿Alguien puede explicar más el caso de uso de job.join() ? Gracias por adelantado.
Explicando más mi caso de uso:
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 } ¿Es este un caso de uso válido para job.join() ?
Es decir, el método callOnlyWhenJobAboveIsDone() solo se llamará cuando finalice doSomethingHere(). ¿Es eso correcto?
Sí.
¿Alguien puede explicar más el caso de uso de job.join()?
En su caso, en realidad no hay necesidad de otro trabajo, simplemente podría escribir:
scope.launch { doSomethingHere() callOnlyWhenJobAboveIsDone() } Eso hará exactamente lo mismo, por lo que no es realmente un caso de uso para un trabajo. Ahora bien, hay otros casos en los que .join() es realmente útil.
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() } }Ahora, para asegurarse de que se realizó la última actualización, por ejemplo, si desea utilizar algunos datos actualizados, puede simplemente:
update.join()en cualquier lugar, también puedes
update.cancel()si quieres.
Lo que es realmente útil sobre launch {} es que no solo devuelve un trabajo, sino que también adjunta el trabajo a CoroutineScope. A través de eso, puede realizar un seguimiento de cada acción asíncrona que ocurre dentro de su aplicación. Por ejemplo, en su interfaz de usuario, puede hacer que cada elemento amplíe CoroutineScope, luego puede cancelar el alcance si el elemento abandona el área renderizada, y todas las actualizaciones/animaciones en él se detendrán.
Job.join() de Kotlin es el equivalente sin bloqueo de Thread.join() de Java.
Entonces, su suposición es correcta: el objetivo de job.join() es esperar a que se complete el job del receptor antes de ejecutar el resto de la rutina actual.
Sin embargo, en lugar de bloquear el subproceso que llama join() (como lo Thread.join() de Java), simplemente suspende la rutina que llama join() , dejando al subproceso actual libre para hacer lo que le plazca (como ejecutar otra rutina) en mientras tanto.