es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Traducción al español: Swift, Combine, cancelar en el vuelo y reemplazar con el nuevo operador de solicitud.

Tengo esta llamada de red para obtener imágenes.

func load() {
    guard let url = URL(string: urlString)
    else { return }

    subscription = URLSession.shared.dataTaskPublisher(for: url)
        .map({ UIImage(data: $0.data) })
        .replaceError(with: nil)
        .receive(on: RunLoop.main)
        .sink(receiveValue: { [weak self] in self?.image = $0 })
}

Esto se activa cuando se llena el campo de texto. Después de cada letra escrita, me gustaría que mi publicador espere la ejecución durante, digamos, 2 segundos, a menos que el usuario haya escrito otra letra. Si eso sucede, me gustaría que el temporizador se reinicie a 2 segundos nuevamente.

¿Existe algún operador de cancelación en tiempo real si se ha enviado una nueva solicitud en el ínterin?

Gracias por toda la ayuda.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para esperar 2 segundos después de que se escriba cada letra, puedes envolver el editor de texto en un operador de retardo (debounce) de la siguiente manera:

    subscription = textField.textPublisher
        .debounce(for: .seconds(2), scheduler: RunLoop.main)
        .compactMap(URL.init(string:))
        .flatMap { url in URLSession.shared.dataTaskPublisher(for: url) }
        .map { UIImage(data: $0.data) }
        .replaceError(with: nil)
        .receive(on: RunLoop.main)
        .sink(receiveValue: { [weak self] in self?.image = $0 })
    

    Esto esperará 2 segundos antes de emitir un valor desde el editor de texto y, si se recibe otro valor antes de que transcurra el intervalo de retardo, el temporizador se reiniciará.

    En cuanto al operador de cancelación, puedes utilizar el operador switchToLatest para cambiar al último editor y cancelar el anterior. Aquí tienes una versión actualizada del código anterior:

    var subscription: AnyCancellable?
    
    func load() {
        subscription = textField.textPublisher
            .debounce(for: .seconds(2), scheduler: RunLoop.main)
            .compactMap(URL.init(string:))
            .map { url in URLSession.shared.dataTaskPublisher(for: url) }
            .switchToLatest()
            .map { UIImage(data: $0.data) }
            .replaceError(with: nil)
            .receive(on: RunLoop.main)
            .sink(receiveValue: { [weak self] in self?.image = $0 })
    }
    

    Con este código, cada vez que se crea un nuevo editor (es decir, se escribe un nuevo texto), se cancelará el anterior y se cambiará al último. Esto garantiza que solo se procese la última solicitud y se cancelen las solicitudes anteriores.

Comments are closed.