代码之家  ›  专栏  ›  技术社区  ›  Jan

多次调用swift闭包是否正确

  •  3
  • Jan  · 技术社区  · 6 年前

    我正在设计一个swift api,在这里我定义了一个协议 EventTransmitter 用一种方法传送一批 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 回复  |  直到 6 年前
        1
  •  3
  •   Fogmeister    6 年前

    如果你想做这样的事情,一个失败的事件列表和成功的事件可能发生,那么我可能会把它们都合并到相同的回调…

    回拨类似…

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

    那么你只需要回拨一次。

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

    这纯粹是从api的角度来看的。两次成功意味着什么?还是三次?或者一次成功然后一次失败,相比之下一次失败然后一次成功。等。。。

    当然,你可以多次调用它,有些地方你可能会想要。例如,存储一个闭包并响应用户交互或其他东西调用它。

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

    另一个可能的选择

    也许你能做的就是把 success failure 关闭处理进入 Event 本身。

    这样,如果事件失败,您可以调用 event.failed() 如果成功了… event.succeeded() 或者别的什么。

    我不知道在这种情况下这是否是个好主意,但肯定是另一种选择:d

    瓦卡瓦玛建议

    你也可以定义你的枚举…

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

    然后让你的回拨像…

    ([EventResult]) -> ()
    

    这样,您只需调用一次,使用一个包含所有单个结果的数组。

    如果结果的顺序与事件的顺序相同,这一点很有用。