Je suis nouveau dans les trucs asynchrones dans Swift, et j'essaie d'implémenter un simple appel asynchrone à une fonction.
A start async B 123.456
Quand je l'exécute, j'obtiens
A start async 123.456 B
Comme la fonction est appelée de manière asynchrone, je me serais attendu à obtenir
import UIKit func doAsyncStuff ( completionHandler: (_ result: Double) -> Void) { print("start async") sleep(5) // to simulate long work let result: Double = 123.456 completionHandler(result) } print("A") doAsyncStuff() { result in print(result) } print("B")
Où me suis-je trompé? Merci beaucoup
4 Réponses :
Le problème est que vous appelez sleep
, qui est une fonction de blocage synchrone, donc vous bloquez le thread principal pendant 5 secondes et rien d'autre ne peut être exécuté entre-temps. Vous devez utiliser DispatchQueue.asyncAfter
pour tester des appels asynchrones simples.
Vous pouvez également savoir que votre fonction n'est pas asynchrone, car vous n'avez pas reçu d'erreur du compilateur pour ne pas marquer votre fermeture comme @escaping
, ce que vous devez faire pour les gestionnaires d'achèvement asynchrone.
func doAsyncStuff(completionHandler: @escaping (_ result: Double) -> Void) { print("start async") DispatchQueue.main.asyncAfter(deadline: .now() + 5) { completionHandler(123.456) } }
Attention, vous appelez votre fonction sur le même thread, donc elle sera synchrone!
Pour l'appeler de manière asynchrone, créez un thread / tâche d'arrière-plan et appelez votre fonction à partir de ce thread d'arrière-plan. Une façon de le faire:
print("A") DispatchQueue.global(qos: .background).async { //this is a background thread, do in it your async stuff doAsyncStuff() { result in print(result) } } print("B")
Merci beaucoup, c'est plus clair maintenant pour moi, DispatchQueue manquait
Utilisez DispatchQueue.main.asyncAfter pour un appel asynchrone dans swift. Votre code devrait donc ressembler à ..
func doAsyncStuff ( completionHandler: (_ result: Double) -> Void) { print("start async") DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { // your code goes from here let result: Double = 123.456 completionHandler(result) } }
Votre fonction n'est pas asynchrone. Chaque ligne de code est exécutée de manière synchrone (c'est-à-dire en attendant que la ligne se termine avant de s'exécuter). Ainsi, sleep (5) interrompt l'exécution au milieu de la fonction et print ("B") n'est appelé qu'après le retour de la fonction.
Vous pouvez utiliser Grand Central Dispatch (GCD) pour exécuter du code de manière asynchrone sur un thread différent. Voici un exemple:
import UIKit func doAsyncStuff ( completionHandler: (_ result: Double) -> Void) { DispatchQueue.global(qos: .background).async { [weak self] in print("start async") sleep(5) let result: Double = 123.456 completionHandler(result) } } print("A") doAsyncStuff() { result in print(result) // This is your completion handler code } print("B")
Votre fonction n'a malheureusement rien à voir avec une exécution asynchrone
ce n'est pas un asynchrone