Les exigences actuelles impliquent un grand nombre d'opérations asynchrones, et les pages réelles penchent de plus en plus vers des applications monopage. À l'avenir, vous pourrez utiliser des frameworks backbone, angulaire, knock-out et autres, mais le problème de la programmation asynchrone est le premier problème auquel il faut faire face. Avec l’essor des nœuds, la programmation asynchrone est devenue un sujet très brûlant. Après une période d'étude et de pratique, quelques détails de la programmation asynchrone sont résumés.
1.Classification de la programmation asynchrone
Les méthodes pour résoudre les problèmes asynchrones incluent généralement : le rappel direct, le mode pub/sub (mode événement), la bibliothèque de contrôle de bibliothèque asynchrone (telle que async, when), la promesse, le générateur, etc.
1.1 Fonction de rappel
La fonction de rappel est une méthode couramment utilisée pour résoudre des problèmes asynchrones. Elle est souvent contactée et utilisée, facile à comprendre et très facile à implémenter dans des bibliothèques ou des fonctions. C'est également une méthode souvent utilisée par tout le monde lors de l'utilisation de la programmation asynchrone.
Mais la méthode de la fonction de rappel présente les problèmes suivants :
1. Il peut former une pyramide imbriquée maléfique et le code est difficile à lire
2. Ne peut correspondre qu'à une seule fonction de rappel, ce qui devient une limitation dans de nombreux scénarios.
Mode pub/sub 1.2 (événement)
Ce mode est également appelé mode événement, qui est l'événementisation des fonctions de rappel. Il est très courant dans les bibliothèques telles que jQuery.
Le modèle d'abonné de publication d'événements lui-même n'a pas de problème d'appels synchrones et asynchrones, mais dans le nœud, les appels d'émission sont principalement déclenchés de manière asynchrone avec la boucle d'événements. Ce mode est souvent utilisé pour découpler la logique métier. L'éditeur d'événements n'a pas besoin de prêter attention aux fonctions de rappel enregistrées, ni au nombre de fonctions de rappel qui peuvent être transférées de manière flexible via les messages.
Les avantages de ce mode sont : 1. Facile à comprendre ; 2. Ne se limite plus à une seule fonction de rappel.
Inconvénients : 1. Nécessité d'utiliser une bibliothèque de classes ; 2. L'ordre des événements et des fonctions de rappel est très important
Il y a deux problèmes avec le code ci-dessus :
a. L'img a effectivement été chargé et la fonction de rappel de chargement n'est liée qu'à ce moment-là. Par conséquent, le rappel ne sera pas exécuté, mais nous espérons toujours exécuter la fonction de rappel correspondante.
b. Incapable de bien gérer les exceptions
Conclusion : le mécanisme d'événement est le plus approprié pour gérer des événements qui se produisent de manière répétée sur le même objet. Il n'est pas nécessaire de prendre en compte l'occurrence d'événements avant que la fonction de rappel ne soit liée.
1.3 Bibliothèque de contrôle asynchrone
Les bibliothèques asynchrones actuelles incluent principalement Q, when.js, win.js, RSVP.js, etc.
La caractéristique de ces bibliothèques est que le code est linéaire et peut être écrit de haut en bas, ce qui est conforme aux habitudes naturelles.
L'inconvénient est que les styles sont différents, ce qui rend la lecture difficile et augmente le coût de l'apprentissage.
Promesse 1.4
La promesse est traduite en chinois par promesse. Ma compréhension personnelle est qu'après l'achèvement asynchrone, elle donnera un résultat externe (succès ou échec) et promet que le résultat ne changera pas. En d'autres termes, la promesse reflète la valeur de retour éventuelle d'une opération (une promesse représente la valeur éventuelle renvoyée par l'achèvement unique d'une opération). À l'heure actuelle, Promise a été introduit dans la spécification ES6 et les navigateurs avancés tels que Chrome et Firefox ont implémenté cette méthode native en interne, ce qui est très pratique à utiliser.
Analysons les caractéristiques de Promise sous les aspects suivants :
1.4.1 Statut
Contient trois états : en attente, réalisé et rejeté. Seules deux transitions peuvent se produire entre les trois états (de en attente--->réalisé, en attente-->rejeté), et la transition d'état ne peut se produire qu'une seule fois.
1.4.2 puis méthode
La méthode then est utilisée pour spécifier la fonction de rappel une fois l'événement asynchrone terminé.
Cette méthode peut être considérée comme la méthode de l'âme de Promise, qui rend Promise pleine de magie. Il existe plusieurs manifestations spécifiques comme suit :
a) La méthode then renvoie Promise. Cela permet des opérations en série de plusieurs opérations asynchrones.
Concernant le traitement de la valeur dans le cercle jaune 1 dans l'image ci-dessus, il s'agit d'une partie plus compliquée de Promise. Le traitement de la valeur est divisé en deux situations : l'objet Promise et l'objet non-Promise.
Lorsque la valeur n'est pas de type Promise, utilisez simplement value comme valeur de paramètre de la résolution de la deuxième Promise ; lorsqu'elle est de type Promise, le statut et les paramètres de promise2 sont entièrement déterminés par la valeur. promsie2 est complètement une marionnette de valeur, promise2 n'est qu'un pont reliant différents asynchrones.
b)实现了多个不同异步库之间的转换。
在异步中存在一个叫thenable的对象,就是指具有then方法的对象,只要一个对象对象具有then方法,就可以对其进行转换,例如:
1.4.3 commonJS Promise/A规范
目前关于Promise的规范存在Promise/A和Promise/A 规范,这说明关于Promise的实现是挺复杂的。
1.4.4 注意事项
La promesse est une valeur sûre果value是对象,那就要小心不要轻易修改value的值。
Générateur 1.5
Toutes les méthodes ci-dessus sont basées sur des fonctions de rappel pour effectuer des opérations asynchrones. Elles ne sont rien de plus qu'une encapsulation de fonctions de rappel. Generator est proposé dans ES6, ce qui ajoute un moyen de résoudre les opérations asynchrones et ne repose plus sur des fonctions de rappel.
La plus grande fonctionnalité de Generator est qu'il peut mettre en pause et redémarrer des fonctions. Cette fonctionnalité est très utile pour résoudre les opérations asynchrones. La combinaison de la pause du générateur avec la gestion des exceptions de la promesse peut résoudre les problèmes de programmation asynchrone de manière plus élégante. Référence d'implémentation spécifique : Kyle Simpson
2. Problèmes de programmation asynchrone
2.1 Gestion des exceptions
a) Les événements asynchrones comprennent deux liens : l'émission de requêtes asynchrones et le traitement des résultats. Ces deux liens sont connectés via une boucle d'événements. Ensuite, lorsque try catch est utilisé pour capturer des exceptions, il doit être capturé séparément.
Le code ci-dessus ne peut pas capturer l'exception dans le rappel, mais ne peut obtenir l'exception que dans le processus de demande. Cela crée un problème : si l'émission de la demande et le traitement de la demande sont effectués par deux personnes, y aura-t-il un problème lors du traitement des exceptions ?
b) Promise implémente la livraison d'exceptions, ce qui apporte certains avantages et garantit que le code n'est pas bloqué dans les projets réels. Mais s’il existe de nombreux événements asynchrones, il n’est pas facile de savoir quel événement asynchrone a provoqué l’exception.
Vous pouvez convertir le code ci-dessus en ce qui suit :
Dans l'exemple ci-dessus, la gestion des exceptions est placée à la fin, de sorte que lorsqu'une exception se produit dans un certain lien, nous ne pouvons pas savoir avec précision quel événement l'a provoquée.
2.2 Problèmes avec jQuery.Deferred
Les opérations asynchrones sont également implémentées dans jQuery, mais l'implémentation n'est pas conforme à la spécification promise/A, principalement dans les aspects suivants :
a. Nombre de paramètres : Standard Promise ne peut accepter qu'un seul paramètre, tandis que jQuery peut transmettre plusieurs paramètres
b. Gestion des exceptions dans le traitement des résultats
On peut voir à partir de cela que Promise effectue le traitement des résultats sur la fonction de rappel et peut capturer les exceptions lors de l'exécution de la fonction de rappel, mais jQuery.Deferred ne le peut pas.