Il y a environ deux catégories d'Api ici: tirer et pousser.
Pull
Async pull Api sont un bon ajustement pour les cas où les données sont extraites à partir d'une source. Cette source peut être un fichier, ou une socket réseau, ou une liste de répertoires, ou quoi que ce soit d'autre. L'essentiel est que le travail est fait de tirer ou de produire des données à partir de la source lorsque demandé.
Async les itérateurs sont la base primitive ici, censé être un générique de manifestation de la notion de pull async source. Dans une telle source, vous:
- Tirer à partir d'un async itérateur en faisant
const promise = ai.next()
- Attendre le résultat de l'utilisation d'
const result = await promise
(ou à l'aide de .then()
)
- Inspecter le résultat pour savoir si c'est une exception (jeté), une valeur intermédiaire (
{ value, done: false })
, ou un fait de signal ({ value: undefined, done: true }
).
Ceci est similaire à la façon de synchroniser les itérateurs sont une générique manifestation de la notion de traction en fonction de synchronisation source de valeur. Les étapes pour une synchronisation itérateur sont exactement les mêmes que ci-dessus, en omettant les "attendre le résultat de l'étape.
Lisible, les ruisseaux sont un cas particulier de la async itérateurs, visent expressément à encapsuler les I/O de sources comme les sockets/fichiers/etc. Ils se sont spécialisés, des Api pour la tuyauterie à inscriptible flux (représentant l'autre moitié de l'I/O de l'écosystème, éviers) et la manipulation de l'résultant de contre-pression. Ils peuvent également être spécialisé pour manipuler des octets dans un efficace "apportez votre propre tampon" de manière. C'est tout ce qui rappelle quelque peu de la façon dont les tableaux sont un cas particulier de la synchronisation des itérateurs, optimisé pour O(1) un accès indexé.
Une autre caractéristique de l'ouverture des Api, c'est qu'ils sont généralement de simple consommateur. Celui qui tire la valeur, maintenant qu'il est, et il n'existe pas dans la source asynchrone itérateur/stream/etc. plus. Il a été retiré par le consommateur.
En général, pull Api fournissent une interface pour la communication avec certains sous-jacente source de données, permettant au consommateur d'exprimer leur intérêt. Ceci est en contraste à...
Pousser
Push Api sont un bon ajustement pour quand quelque chose est de générer des données, et les données générées ne se soucie pas de savoir si quelqu'un la veut ou pas. Par exemple, peu importe si quelqu'un est intéressé, il est toujours vrai que votre souris est déplacée, et puis vous avez cliqué quelque part. Vous voulez manifester ces faits avec un push API. Ensuite, les consommateurs---peut-être plusieurs d'entre eux---pouvez vous abonner, à pousser des notifications au sujet de telles choses se produire.
L'API en elle-même ne se soucie pas de savoir si zéro, un, ou plusieurs consommateurs s'abonnent. C'est juste manifestant un fait à propos de choses qui s'est passé dans l'univers.
Les événements sont une simple manifestation de cette. Vous pouvez vous abonner à un EventTarget dans le navigateur, ou EventEmitter dans Node.js et soyez informé des événements qui sont expédiés. (Généralement, mais pas toujours, par la EventTarget du créateur).
Les phénomènes Observables sont une version plus raffinée de EventTarget. Leur principale innovation est que l'abonnement en lui-même est représenté par un objet de classe, les Observables, que vous pouvez ensuite appliquer combinators (tels que filtre, map, etc...) plus de. Ils font aussi le choix de réunir les trois signaux (généralement nommé prochaine, complète, et l'erreur) en un seul, et de donner à ces signaux spéciaux de la sémantique, de sorte que les combinators les respecter. C'est par opposition à EventTarget, où les noms d'événements n'ont sémantique (aucune méthode de EventTarget se soucie de savoir si votre événement est "complete" vs "faa"). EventEmitter dans le Nœud a une certaine version de ce spécial-la sémantique de l'approche "erreur" événements peuvent se bloquer le processus, mais c'est assez primitif.
Une autre fonctionnalité intéressante de phénomènes observables sur le cours des événements, c'est que généralement, seul le créateur de l'observable, peuvent être la cause de générer de ceux suivant/erreur/complète des signaux. Alors que sur EventTarget, n'importe qui peut appeler dispatchEvent(). Cette séparation des responsabilités permet un meilleur code, dans mon expérience.
Mais en fin de compte, à la fois les événements et les phénomènes observables sont de bonne Api pour pousser les occurrences dans le monde, pour les abonnés qui peuvent se brancher et régler à tout moment. Je dirais observables sont le plus moderne pour ce faire, et plus agréable à certains égards, mais les événements sont de plus en plus répandue et bien compris. Donc, si quelque chose a été prévu pour remplacer les événements, il serait observables.
Poussez <-> pull
Il est intéressant de noter que vous pouvez construire une ou l'autre approche sur le dessus de l'autre en un clin d'œil:
- Pour construire pousser sur le dessus de tirer, être constamment en tirant à partir de la liste de l'API, puis poussez les blocs pour tous les consommateurs.
- Pour construire tirez sur le dessus de pousser, de s'abonner à la push API immédiatement, à créer une zone tampon qui s'accumule tous les résultats, et quand quelqu'un tire, le saisir à partir de la mémoire tampon. (Ou attendre jusqu'à ce que le tampon est vide, si votre consommation est en tirant plus vite que la enveloppé push API est de pousser.)
Ce dernier est généralement beaucoup plus de code à écrire que l'ancien.
Un autre aspect de l'essayer pour s'adapter entre les deux est que seulement tirer Api permet de communiquer facilement la contre-pression. Vous pouvez ajouter un canal latéral à pousser des Api pour leur permettre de communiquer à la pression de retour vers la source; je pense Dart fait cela, et certaines personnes essaient de créer des évolutions des observables qui ont cette capacité. Mais c'est de l'OMI beaucoup plus difficile que tout juste correctement du choix d'un pull API en premier lieu. Le revers de la médaille, c'est que si vous utilisez un push API pour exposer fondamentalement basé sur l'extraction de la source, vous ne serez pas en mesure de communiquer la contre-pression. C'est l'erreur faite avec le WebSocket et XMLHttpRequest Api, par la manière.
En général, je trouve les tentatives pour unifier le tout dans un API en l'enveloppant d'autres erronée. Pousser et tirer distincts, pas-très-chevauchement des domaines où elles fonctionnent bien, et dire que nous devrions choisir l'un des quatre Api que vous avez mentionné et le bâton avec elle, comme certaines personnes le font, est à courte vue et conduit à adopter de code.