Sie können nicht einen Fehler aus, aber Sie können einen Fehler zurück:
Zuerst müssen Sie auch Ihre Berufung Funktion asynchron machen:
func execute(argument: someArg, completion: @escaping (Value?, Error?)->()) {
queue.async {
do {
// compute value here:
...
completion(value, nil)
} catch {
completion(nil, error)
}
}
}
Der Abschluss Handler nimmt einen Parameter, wir konnten say ist ein "Ergebnis", das entweder den Wert oder einen Fehler enthält. Hier haben wir ein Tupel (Value?, Error?)
, wobei Value
der Typ ist, der von der Task berechnet wird. Stattdessen könnten Sie dafür eine handlichere Swift Enum nutzen, z. Result<T>
oder Try<T>
(Sie möchten vielleicht im Internet suchen).
Dann verwenden Sie es wie folgt:
execute(argument: "Some string") { value, error in
guard error == nil else {
// handle error case
}
guard let value = value else {
fatalError("value is nil") // should never happen!
}
// do something with the value
...
}
einige Regeln, die helfen könnten:
Wenn eine Funktion intern eine asynchrone Funktion aufruft, ist es unvermeidlich als auch eine asynchrone Funktion wird. *)
Eine asynchrone Funktion sollte einen Abschluss-Handler haben (sonst ist es eine Art "Feuer und Vergessen").
Der Abschluss-Handler muss aufgerufen werden, egal was.
muss die Abschluss-Handler asynchron (bezüglich dem die Anrufer) aufgerufen werden soll
Der Abschluss-Handler auf einem privaten Ausführungskontext bezeichnet werden (auch bekannt als Absende-Warteschlange), sofern nicht die Funktion einen Parameter in dem ausführen zu spezifizieren hat der Beendigungshandler. Verwenden Sie niemals den Hauptthread oder die Hauptversandwarteschlange, es sei denn, Sie geben dies explizit in den Dokumenten an, oder Sie möchten absichtlich Deadlocks riskieren.
*) Sie können es zu machen, zwingen synchron Semaphore verwendet, die den aufrufenden Thread blockieren. Dies ist jedoch ineffizient und wird nur selten benötigt.
Nun, Sie könnten daraus schließen, dass dies etwas umständlich aussieht. Zum Glück gibt es Hilfe - Sie könnten nach Future
oder Promise
suchen, die dies schön umhüllen und den Code prägnanter und verständlicher machen können.
Hinweis: Im Komponententest würden Sie die Erwartungen verwenden, um asynchrone Aufrufe zu verarbeiten (siehe XCTest-Framework).