多次调用Swift闭包是否正确

时间:2018-06-25 10:47:05

标签: swift api-design

我正在设计一个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
    }
})

1 个答案:

答案 0 :(得分:3)

如果您想做这样的事情,在该事件中可能会出现失败事件和成功事件的列表,那么我可能会将它们都合并到同一个回调中...

类似...的回调

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

然后,您只需调用一次回调即可。

如果您有一个可以捕获回调状态的枚举,那么我建议只让它运行一次。

这纯粹是从API的角度来看。处理两次成功意味着什么?还是三遍?或成功与失败相比,失败与成功相比。等等...

当然,您可以多次调用它,并且在某些地方可能需要。例如,存储一个闭包并响应用户交互或诸如此类调用它。

但是对于这样的情况,如果有一个请求,我建议使用所有必要的信息对其进行一次调用。

另一个可能的选择

也许您可以做的是将successfailure闭包处理合并到Event本身。

这样,如果事件失败,您可以呼叫event.failed()并成功调用... event.succeeded()或其他东西。

我不知道这是否是个好主意,但这当然是另一种选择:D

由vacawama建议

您也可以将枚举定义为...

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

然后使您的回调像...

([EventResult]) -> ()

通过这种方式,您只需将所有单个结果的一个数组调用一次即可。

如果结果顺序与事件顺序相同很重要,这将很有用。