Правильно ли вызывать замыкание Swift несколько раз? - PullRequest
0 голосов
/ 25 июня 2018

Я разрабатываю Swift API, в котором я определяю протокол EventTransmitter с методом передачи пакета Events.Обработка пакета Events может заканчиваться списком как успешных, так и неудачных событий.

Таким образом, любая реализация этого протокола должна вызывать завершение с событиями, которые завершились неудачей, и / или событиями, которые произошли успешно.

public enum EventResult {

    /// When the event was transmitted correctly.
    case success([Event])

    /// When the event failed and should be discarded
    case failure([Event])
}

public protocol EventTransmitter {

    func transmit(events: [Event], completion: @escaping (EventResult) -> Void)
}

При использовании вышеуказанного протокола тот, кто его реализует, должен дважды вызвать завершение:

public class HTTPTransmitter: EventTransmitter {

    public func transmit(events: [Event], completion: @escaping (EventResult) -> Void) {

        let failedEvents =  ...
        let successEvents = ...

        completion(.failure(failedEvents))

        completion(.success(successEvents))
    }
}

И использование будет

transmitter.transmit(events: events, completion: { result in
    switch result {
    case .success(let events):
        // handle success events
    case .failure(let events):
        // handle failed events
    }
})

Правильно ли требовать вызывать одно замыкание завершения несколько раз?

Или было бы более целесообразно иметь разные замыкания для каждого случая:

public protocol EventTransmitter {

    typealias EventCallback = (([Event]) -> Void)

    func transmit(events: [Event], onSuccess: @escaping EventCallback, onFailure: @escaping EventCallback)
}

1 Ответ

0 голосов
/ 25 июня 2018

Если вы хотите сделать что-то подобное, где может произойти список неудачных и успешных событий, я бы, вероятно, объединил их обоих в один и тот же обратный вызов ...

Обратный вызов что-то вроде ...

typealias EventCallBack = (succeeded: [Event], failed: [Event]) -> ()

Тогда вам нужно будет вызвать обратный вызов только один раз.

В случае, если у вас есть перечисление, которое фиксирует состояние обратного вызова, тогда я бы предложил сделать его запуск только один раз.

Это чисто с точки зрения API.Что значит иметь дело с успехом дважды?Или три раза?Или успех, а затем неудача по сравнению с неудачей, а затем успехом.и т.д. ...

Конечно, вы МОЖЕТЕ звонить несколько раз, и есть места, где вы можете захотеть.Например, сохраняя замыкание и вызывая его в ответ на взаимодействие с пользователем или что-то в этом роде.

Но для чего-то подобного, когда есть один запрос, я бы предложил один раз вызвать его со всей необходимой информацией.

Другая возможная альтернатива

Возможно, вы могли бы включить обработку закрытия success и failure в саму Event.

Таким образом, еслисобытие завершается неудачно, вы можете вызвать event.failed() и, если оно выполнено успешно ... event.succeeded() или что-то в этом роде.

Я не знаю в данном конкретном случае, если это хорошая идея, но это, безусловно, другой вариант:D

Предложено vacawama

Вы также можете определить свой enum как ...

enum EventResult {
    case success(Event)
    case failed(Event)
}

И затем сделать свой обратный вызов как ...

([EventResult]) -> ()

Таким образом, вы просто вызываете его один раз с одним массивом всех отдельных результатов.

Это было бы полезно, если важно, чтобы порядок результатов был одинаковымкак порядок событий.

...