Aby rozwinąć wspaniałe punkty: @dasblinkenlight i @Sulthan dokonano - oto mały przykład, w jaki sposób można osiągnąć funkcję żądania, aby odnieść sukces i zamknięcie awarii, w wygodnej składni, którą chcesz.
Najpierw musisz zdefiniować nową klasę, która będzie reprezentować "procedurę obsługi wyników". To właśnie będą przechodzić funkcje success
i failure
, co pozwala dodawać wiele końcowych zamknięć w celu uzupełnienia logiki bloku zakończenia. Będziemy chcieli to wyglądać mniej więcej tak:
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
}
}
To pozwoli na zdefiniowanie wielu sukces lub niepowodzenie zamknięcia zostanie zawarta w dniu zakończenia. Jeśli w rzeczywistości nie potrzebujesz zdolności do wielokrotnego zamykania, możesz uprościć klasę, usuwając tablice - i zamiast tego po prostu śledź ostatnie dodane bloki sukcesów i niepowodzenia.
Teraz wszystko co musisz zrobić, to określić funkcję, która generuje nowy ResultHandler
instancji, a następnie robi danego żądania asynchronicznego, przy czym metoda invokeCallbacks
jest wywoływana po zakończeniu:
func doRequest(input:Input) -> ResultHandler {
let resultHandler = ResultHandler()
doSomethingAsynchronous(resultHandler.invokeCallbacks)
return resultHandler
}
Teraz można nazwać to jak to:
doRequest(input).success {result in
print("success, with:", result)
}.failure {
print("fail :(")
}
Jedyną rzeczą, aby pamiętać, to funkcja doSomethingAsynchronous
będzie miał do wysłania jej zakończenia blok z powrotem do głównego wątku, w celu zapewnienia bezpieczeństwa wątku.
Pełny projekt (z dodatkiem przykład na wykorzystanie): https://github.com/originaluser2/Callback-Closure-Chaining
Można powrócić do obiektu, który ma '' success' i mienia failure' i 'success' setter zwraca również, że btw jesteś można użyć promiseKit, który to robi http://promisekit.org/ –
Możesz wypróbować mój artykuł, który robi właśnie to: [Funkcje łączenia asynchronicznego w Swift] (https://medium.com/@jhoomuck/composing-asynchronous-functions- in-swift-acd24cf5b94a) – zeitgeist7