Чтобы расширить основные моменты @dasblinkenlight и @Sulthan — вот небольшой пример того, как вы можете заставить свою функцию запроса выполнять успешное и неудачное закрытие в удобном синтаксисе, который вам нужен.
Во-первых, вам нужно определить новый класс для представления «обработчика результатов». Это то, что будут передавать ваши функции success
и failure
, что позволит вам добавить несколько завершающих замыканий, чтобы составить логику вашего блока завершения. Вы хотите, чтобы это выглядело примерно так:
class ResultHandler {
typealias SuccessClosure = RequestHandler.Output->Void
typealias FailureClosure = Void->Void
// the success and failure callback arrays
private var _successes = [SuccessClosure]()
private var _failures = [FailureClosure]()
/// Invoke all the stored callbacks with a given callback result
func invokeCallbacks(result:RequestHandler.Result) {
switch result {
case .Success(let output): _successes.forEach{$0(output)}
case .Failure: _failures.forEach{$0()}
}
}
// remove all callbacks – could call this from within invokeCallbacks
// depending on the re-usability of the class
func removeAllCallbacks() {
_successes.removeAll()
_failures.removeAll()
}
/// appends a new success callback to the result handler's successes array
func success(closure:SuccessClosure) -> Self {
_successes.append(closure)
return self
}
/// appends a new failure callback to the result handler's failures array
func failure(closure:FailureClosure) -> Self {
_failures.append(closure)
return self
}
}
Это позволит вам определить несколько успешных или неудачных закрытий, которые будут выполняться по завершении. Если вам на самом деле не нужна емкость для нескольких замыканий, вы можете упростить класс, удалив массивы и вместо этого просто отслеживая последние добавленные блоки успешного и неудачного завершения.
Теперь все, что вам нужно сделать, это определить функцию, которая генерирует новый экземпляр ResultHandler
, а затем выполняет заданный асинхронный запрос с вызовом метода invokeCallbacks
по завершении:
func doRequest(input:Input) -> ResultHandler {
let resultHandler = ResultHandler()
doSomethingAsynchronous(resultHandler.invokeCallbacks)
return resultHandler
}
Теперь вы можете назвать это так:
doRequest(input).success {result in
print("success, with:", result)
}.failure {
print("fail :(")
}
Единственное, что следует отметить, это то, что ваша функция doSomethingAsynchronous
должна будет отправить свой блок завершения обратно в основной поток, чтобы обеспечить потокобезопасность.
Полный проект (с добавленным примером использования): https://github.com/hamishknight/Callback-Closure-Chaining
person
Hamish
schedule
09.05.2016
success
иfailure
, и сеттерsuccess
также возвращает это, кстати, вы можете использовать promiseKit, который делает это promisekit. организация - person Daniel Krom   schedule 09.05.2016