Hola, tengo un caso en el que necesito llamar al mismo método en varias tareas. Quiero tener la posibilidad de llamar a este método uno por uno (sincronización) no en modo paralelo. Se parece a eso:
var isReadyToRefresh: Bool = true func refresh(value: Int) async { try! await Task.sleep(nanoseconds: 100_000_000) // imitation API CALL isReadyToRefresh = false print("Try to refresh: \(value)") } func mockCallAPI(value: Int) async { if isReadyToRefresh { await refresh(value: value) } } Task { await mockCallAPI(value: 1) } Task { await mockCallAPI(value: 2) }producción:
Intenta actualizar: 1
Intenta actualizar: 2
mi salida requerida:
Intente actualizar: 1 O Intente actualizar 2. Depende de qué tarea se haya llamado como primera.
¿Algunas ideas?
Tu dijiste:
Quiero que [el segundo intento] espere a que finalice la primera actualización de la API
Puede guardar una referencia a su Task y, si la encuentra, await . Si no lo encuentra, inicie la tarea:
actor Refresh { var task: Task<Void, Never>? func refresh(value: Int) async { try! await Task.sleep(nanoseconds: 100_000_000) // imitation API CALL print("Try to refresh: \(value)") } func mockCallAPI(value: Int) async { if let task = self.task { _ = await task.result return } task = Task { await refresh(value: value) task = nil } } }Apple mostró un ejemplo de este patrón en el código provisto con el video WWDC 2021, Proteger el estado mutable con actores Swift (pero este código no está en el sitio web; solo se proporciona en la aplicación para desarrolladores). Consulte ¿Cómo evitar que el reingreso de actores genere solicitudes duplicadas?
Su ejemplo es más complicado (un patrón para evitar que las solicitudes de red duplicadas sean iniciadas por algún caché/descargador de imágenes), pero el núcleo de la idea es el mismo: guardar y await la Task .
¿Por qué deben estar en tareas separadas si no desea que se ejecuten en paralelo? Await significa que el código no progresará más que después de que se complete la tarea, debido al subproceso cooperativo que se puede usar para hacer el subproceso que lo inició. otra cosa, como procesar más usando la interacción u otras tareas, de hecho, debido a que las tiene en tareas separadas, está pidiendo que se ejecuten en paralelo, es posible que el bloque que las contiene entre en el mismo traer y tendrá otra dos tareas, en cuyo caso debe esperar un resultado de la tarea del contenedor que diga que se han completado, y el código que ingresó al bloque verifica esto para continuar.