Vous savez peut-être que l'environnement d'exécution du langage Javascript est "single thread".
Le soi-disant « fil unique » signifie qu'une seule tâche peut être accomplie à la fois. S'il y a plusieurs tâches, elles doivent être mises en file d'attente. Une fois la tâche précédente terminée, la tâche suivante sera exécutée, et ainsi de suite.
L'avantage de ce mode est qu'il est relativement simple à mettre en œuvre et l'environnement d'exécution est relativement simple ; l'inconvénient est que tant qu'une tâche prend beaucoup de temps, les tâches suivantes doivent être mises en file d'attente, ce qui retardera l'exécution. de l'ensemble du programme. L'absence de réponse courante du navigateur (mort suspendue) est souvent causée par un certain morceau de code Javascript exécuté pendant une longue période (comme une boucle infinie), ce qui bloque la page entière à cet endroit et empêche d'autres tâches d'être effectuées.
Afin de résoudre ce problème, le langage Javascript divise le mode d'exécution des tâches en deux types : synchrone (Synchronous) et asynchrone (Asynchronous).
Le « mode synchrone » est le mode du paragraphe précédent. Cette dernière tâche attend la fin de la tâche précédente avant de l'exécuter. L'ordre d'exécution du programme est cohérent et synchrone avec l'ordre des tâches ; complètement différent. Chaque tâche a une ou plusieurs fonctions de rappel (rappel). Une fois la tâche précédente terminée, la tâche suivante n'est pas exécutée, mais la fonction de rappel est exécutée sans attendre la fin de la tâche précédente, donc. l'exécution du programme L'ordre est incohérent et asynchrone avec l'ordre des tâches.
Le "mode asynchrone" est très important. Du côté du navigateur, les opérations de longue durée doivent être effectuées de manière asynchrone pour éviter que le navigateur ne réponde. Le meilleur exemple est celui des opérations Ajax. Du côté du serveur, le « mode asynchrone » est même le seul mode, car l'environnement d'exécution est monothread. Si toutes les requêtes http peuvent être exécutées de manière synchrone, les performances du serveur chuteront fortement et il perdra bientôt sa réponse.
Cet article résume 4 méthodes de programmation en « mode asynchrone ». Les comprendre vous permettra d'écrire des programmes Javascript avec une structure plus raisonnable, de meilleures performances et une maintenance plus facile.
1. Fonction de rappel
Il s'agit de la méthode la plus basique de programmation asynchrone.
Supposons qu'il y ait deux fonctions f1 et f2, et que cette dernière attend le résultat de l'exécution de la première.
Si f1 est une tâche fastidieuse, vous pouvez envisager de réécrire f1 et d'écrire f2 comme fonction de rappel de f1.
setTimeout(function () {
// Code de tâche de f1
rappel();
}, 1000);
}
En utilisant cette méthode, nous transformons les opérations synchrones en opérations asynchrones. F1 ne bloquera pas le fonctionnement du programme, cela équivaut à exécuter d'abord la logique principale du programme et à reporter l'exécution des opérations fastidieuses.
L'avantage de la fonction de rappel est qu'elle est simple, facile à comprendre et à déployer. L'inconvénient est qu'elle n'est pas propice à la lecture et à la maintenance du code. Les différentes parties sont fortement couplées (Coupling), le processus sera. très déroutant, et chaque tâche ne peut spécifier qu'une seule fonction de rappel.
2. Surveillance des événements
Une autre façon de penser consiste à utiliser le modèle événementiel. L'exécution d'une tâche ne dépend pas de l'ordre du code, mais de la survenance d'un événement.
Prenons f1 et f2 comme exemple. Tout d’abord, liez un événement à f1 (jQuery est utilisé ici).
setTimeout(function () {
// Code de tâche de f1
f1.trigger('done');
}, 1000);
}
L'avantage de cette méthode est qu'elle est relativement facile à comprendre, qu'elle peut lier plusieurs événements, que chaque événement peut spécifier plusieurs fonctions de rappel et qu'elle peut être « découplée », ce qui est propice à la modularisation. L'inconvénient est que l'ensemble du programme doit être piloté par des événements et que le processus en cours devient très flou.
3. Publier/Abonnez-vous
L'« événement » de la section précédente peut être compris comme un « signal ».
Nous supposons qu'il existe un "centre de signal". Lorsqu'une certaine tâche est exécutée, elle "publie" un signal au centre de signal. D'autres tâches peuvent "s'abonner" au signal du centre de signal pour savoir ce que vous pouvez. commencez à l’exécuter vous-même. C'est ce qu'on appelle le « modèle de publication-abonnement » (modèle de publication-abonnement), également connu sous le nom de « modèle d'observateur » (modèle d'observateur).
Il existe de nombreuses implémentations de ce modèle. Celle utilisée ci-dessous est Tiny Pub/Sub de Ben Alman, qui est un plug-in pour jQuery.
Tout d'abord, f2 s'abonne au signal "done" du jQuery "Signal Center".
setTimeout(function () {
// Code de tâche de f1
jQuery.publish("done");
}, 1000);
}
De plus, une fois l'exécution de f2 terminée, vous pouvez également vous désinscrire.
4. Objet Promesses
L'objet Promises est une spécification proposée par le groupe de travail CommonJS pour fournir une interface unifiée pour la programmation asynchrone.
En termes simples, l'idée est que chaque tâche asynchrone renvoie un objet Promise, qui possède une méthode then qui permet de spécifier une fonction de rappel. Par exemple, la fonction de rappel f2 de f1 peut s'écrire :
var dfd = $.Deferred();
setTimeout(function () {
// Code de tâche de f1
dfd.resolve();
}, 500);
Retourner dfd.promise ;
}
Par exemple, spécifiez plusieurs fonctions de rappel :