Qu'est-ce que “rappel de l'enfer”, et comment et pourquoi RX résoudre?
Quelqu'un peut-il donner une définition claire avec un exemple simple qui explique ce qu'est un "rappel de l'enfer" pour quelqu'un qui ne connais pas le JavaScript et node.js ?
Quand (dans ce genre de paramètres) le "rappel de l'enfer" du problème de se produire?
Pourquoi faut-il se produire?
Est "rappel de l'enfer" toujours liées à des calculs asynchrones?
Ou peut "rappel de l'enfer" se produisent également dans un seul thread de l'application?
J'ai pris le Réactif de Cours sur Coursera et Erik Meijer a dit dans une de ses conférences que RX résout le problème de "rappel de l'enfer". J'ai demandé qu'est ce qu'un "rappel de l'enfer" sur la Coursera forum mais je n'ai pas de réponse claire.
Après avoir expliqué "rappel de l'enfer" sur un exemple simple, pourriez-vous également de montrer comment RX résout le "rappel de l'enfer problème" sur ce simple exemple?
Vous devez vous connecter pour publier un commentaire.
1) qu'est Ce qu'un "rappel de l'enfer" pour quelqu'un qui ne connais pas le javascript et node.js ?
Cette autre question a quelques exemples de Javascript rappel de l'enfer: Comment éviter les longues imbrication des fonctions asynchrones Node.js
Le problème en Javascript, c'est que la seule façon de "geler" un calcul et d'avoir le "reste" exécuter ceux-ci (de manière asynchrone) c'est que "le reste" à l'intérieur d'un rappel.
Par exemple, dire que je veux exécuter du code qui ressemble à ceci:
Ce qui se passe si maintenant je veux faire de la getData fonctions asynchrone, ce qui signifie que je reçois une chance d'exécuter du code des autres alors que je suis en attente pour eux de retrouver leurs valeurs? En Javascript, le seul moyen serait de réécrire tout ce qui touche à la async calcul à l'aide de continuation passing style:
Je ne pense pas que j'ai besoin de convaincre quiconque que cette version est plus laid que la précédente. 🙂
2) Lorsque (dans ce genre de paramètres) le "rappel de l'enfer" du problème de se produire?
Lorsque vous avez beaucoup de fonctions de rappel dans votre code! Il devient plus difficile de travailler avec eux plus d'eux que vous avez dans votre code, et il devient particulièrement mauvais quand vous avez besoin de faire des boucles, les blocs try-catch et des choses comme ça.
Par exemple, pour autant que je sais, en JavaScript la seule façon d'exécuter une série de fonctions asynchrones où l'on est courir après le précédent renvoie est à l'aide d'une fonction récursive. Vous ne pouvez pas utiliser une boucle for.
Au lieu de cela, nous avons besoin de nous pour la fin de l'écriture:
Le nombre de questions que nous recevons ici sur StackOverflow demander comment faire ce genre de chose, c'est un témoignage de la façon dont déroutant c'est 🙂
3) Pourquoi faut-il se produire ?
Cela se produit parce que en JavaScript le seul moyen de retarder un calcul de sorte qu'il s'exécute après l'appel asynchrone retourne est de mettre le retard de code à l'intérieur d'une fonction de rappel. Vous ne pouvez pas attendre de code qui a été écrit en traditionnelle synchrone de style si vous vous retrouvez avec imbriquée des rappels de partout.
4) Ou "rappel de l'enfer" se produisent également dans un seul thread de l'application?
La programmation asynchrone a à faire avec la concurrence d'accès, tandis qu'un seul thread a à voir avec le parallélisme. Les deux concepts sont en fait pas la même chose.
Vous pouvez toujours avoir simultanées code dans un seul thread contexte. En fait, le JavaScript, la reine de rappel de l'enfer, est mono-thread.
Quelle est la différence entre concurrence et parallélisme?
5) pourriez-vous également de montrer comment RX résout le "rappel de l'enfer problème" sur cet exemple simple.
Je ne sais rien à propos de RX en particulier, mais habituellement, ce problème est résolu par l'ajout d'un support natif pour le calcul asynchrone dans le langage de programmation. Les implémentations peuvent varier et inclure: asynchrone, les générateurs, les coroutines, et callcc.
En Python on peut mettre en œuvre que la précédente boucle exemple avec quelque chose le long des lignes de:
Ce n'est pas le code complet, mais l'idée est que le "rendement" des pauses pour notre boucle jusqu'à ce que quelqu'un appelle myGen.next(). L'important, c'est que l'on peut encore écrire le code à l'aide d'une boucle for, sans avoir besoin de tourner hors de la logique de "l'intérieur" comme nous avons eu à faire dans cette récursive
loop
fonction.Il suffit de répondre à la question: pourriez-vous s'il vous plaît également de montrer comment RX résout le "rappel de l'enfer problème" sur ce simple exemple?
La magie est
flatMap
. Nous pouvons écrire le code suivant dans Rx pour @hugomg exemple:C'est comme vous écrivez quelque synchrone FP codes, mais en fait, vous pouvez les faire asynchrone par
Scheduler
.De répondre à la question de comment Rx résout rappel de l'enfer:
Commençons d'abord par décrire rappel de l'enfer à nouveau.
Imaginer un cas étaient nous devons faire http obtenir trois ressources de la personne, de la planète et de la galaxie. Notre objectif est de trouver la galaxie, la personne vit dans. Nous devons d'abord obtenir de la personne, puis de la planète, puis la galaxie. C'est trois rappels pour les trois opérations asynchrones.
Chaque rappel est imbriqué. Chaque interne de rappel est dépendant de ses parents. Cela conduit à la "pyramide de la mort" style de rappel de l'enfer. Le code ressemble a > signe.
Pour résoudre ce dans RxJs vous pourriez faire quelque chose comme ça:
Avec le
mergeMap
AKAflatMap
opérateur de vous pourrait rendre plus succincte:Comme vous pouvez le voir, le code est aplatie et contient une seule chaîne d'appels de méthode. Nous n'avons pas de "pyramide de la mort".
Par conséquent, la fonction de rappel de l'enfer est à éviter.
Dans le cas où vous vous le demandiez, promesses sont une autre façon d'éviter de rappel de l'enfer, mais les promesses sont désireux, pas paresseux comme observables et (en général) vous ne pouvez pas annuler comme facilement.
Rappel de l'enfer est le code où l'utilisation de la fonction rappels dans async code devient obscur ou difficile à suivre. Généralement, quand il y a plus d'un niveau d'indirection, code à l'aide de rappels peuvent devenir plus difficiles à suivre, plus difficile à refactoriser, et plus difficile à tester. Une odeur de code est à de multiples niveaux de retrait en raison de passer plusieurs couches de littéraux de fonction.
C'est souvent le cas lorsque le comportement a des dépendances, c'est à dire quand Une doivent se produire avant que B doit se faire avant que C. Ensuite, vous obtenez le code comme ceci:
Si vous avez beaucoup de dépendances comportementales dans votre code comme celui-ci, il peut devenir gênant rapide. Surtout si c'branches...
Ce n'est pas cela. Comment pouvons-nous rendre le code asynchrone exécuter dans un ordre déterminé, sans avoir à passer tous ces rappels autour?
RX est l'abréviation de "reactive extensions". Je ne l'ai pas utilisé, mais une recherche sur Google suggère que c'est un événement à base de cadre, qui fait sens. Événements sont un modèle commun pour faire de code à exécuter dans l'ordre, sans création de fragile de couplage. Vous pouvez faire C d'écouter l'événement "bFinished' qui se produit seulement après que B est appelé l'écoute de 'finit'. Vous pouvez facilement ajouter des étapes supplémentaires ou d'étendre ce genre de comportement, et peut de tester facilement que votre code s'exécute dans l'ordre en se contentant de radiodiffusion des événements dans votre cas de test.
Si vous n'avez pas de connaissances sur le rappel et l'enfer de rappel il n'y a pas de problème.Ist, c'est que le retour d'appel et de retour d'appel de l'enfer.Par exemple:l'enfer de retour d'appel, c'est comme une l'on peut stocker une classe à l'intérieur d'une classe.Comme vous l'avez entendu à propos de qui nichaient dans le C, le C++ le langage.Imbriquée Signifie qu'une classe à l'intérieur d'une autre classe.
Utilisation jazz.js
https://github.com/Javanile/Jazz.js
il simplifier comme ceci: