Qu'est-ce qui détermine quelles fonctions Javascript bloquent ou non bloquent?

27

Je fais du Javascript basé sur le Web (vanilla JS, jQuery, Backbone, etc.) depuis quelques années maintenant, et récemment j'ai travaillé avec Node.js. Il m'a fallu un certain temps pour me familiariser avec la programmation "non bloquante", mais je me suis maintenant habitué à utiliser les rappels pour les opérations d'E / S et ainsi de suite.

Je comprends que Javascript est un thread unique par nature. Je comprends le concept de la «file d'attente d'événements» du nœud. Ce que je ne comprends pas, c'est ce qui détermine si une opération javascript individuelle est "bloquante" par rapport à "non bloquante". Comment savoir de quelles opérations je peux dépendre pour produire une sortie de façon synchrone à utiliser dans un code ultérieur, et à quelles opérations je dois passer des rappels pour pouvoir traiter la sortie une fois l'opération initiale terminée? Y a-t-il une liste de fonctions Javascript quelque part qui sont asynchrones / non bloquantes, et une liste de celles qui sont synchrones / bloquantes? Qu'est-ce qui empêche mon application Javascript d'être une condition de course géante?

Je sais que les opérations qui prennent beaucoup de temps, comme les opérations d'E / S dans le nœud et les opérations AJAX sur le Web, nécessitent qu'elles soient asynchrones et utilisent donc des rappels - mais qui détermine ce qui peut être qualifié de "long temps"? Existe-t-il une sorte de déclencheur dans ces opérations qui les supprime de la "file d'attente d'événements" normale? Sinon, qu'est-ce qui les différencie des opérations simples telles que l'attribution de valeurs à des variables ou la boucle à travers des tableaux, sur lesquels il semble que nous pouvons compter pour terminer de manière synchrone?

Peut-être que je n'y pense même pas correctement - en espérant que quelqu'un puisse me redresser. Merci!

Sean
la source
c'est quelque chose que j'ai trouvé très utile, même si votre réponse à votre question est que vous devez vérifier la documentation pour savoir si les méthodes sont asynchrones.
Anastasios Andronidis

Réponses:

13

En général, toute fonction qui fait du réseautage ou utilise des minuteries pour faire des choses sur une période de temps sera asynchrone.

Si la fonction prend un rappel, vous pouvez voir à quoi le rappel est utilisé et il sera généralement évident qu'il est asynchrone ou non. Si la fonction n'offre pas de rappel, elle n'a aucun moyen de communiquer les résultats asynchrones, elle n'est donc probablement pas asynchrone.

Il n'y a aucun moyen infaillible de dire avec certitude. Il doit être précisé dans le document pour une fonction ou évident d'après le fonctionnement de l'interface.

Les opérations asynchrones sont différentes sous les couvertures des opérations synchrones dans la mesure où les opérations asynchrones ont la notion de configurer une opération, de démarrer l'opération et d'être ensuite notifié plus tard de la progression, de l'achèvement ou des erreurs dans l'opération. L'itération d'un tableau est une opération synchrone. Il n'a aucun de ces problèmes. Le code s'exécute simplement de manière synchrone. L'émission d'un appel ajax consiste à enregistrer un rappel pour les notifications d'état, puis à démarrer l'appel ajax, puis à continuer à exécuter d'autres javascript et, quelque temps plus tard, le rappel est appelé avec un changement d'état sur l'appel ajax (tel que l'achèvement).

jfriend00
la source
1
En complément, certaines fonctions Javascript sont à la fois bloquantes et non bloquantes, selon leurs paramètres. Par exemple, XMLHttpRequest.openpossède un asyncparamètre booléen qui contrôle si l'appel ultérieur à sendest asynchrone.
Brian
Je n'ai tout simplement pas trouvé cette réponse utile et généralement expliquée.
Mehdi Raash
@MehdiRaash - La réponse est que vous le comprenez à partir de la documentation ou de l'interface. Il n'y a pas d'autre moyen. Voilà ce que cela dit. Je ne sais pas trop à quoi vous vous attendiez. Il n'y a pas de réponse miracle.
jfriend00
6

D'après ce que je comprends, vous ne demandez pas ce que vous devez rendre asynchrone, mais comment savoir si une fonction est asynchrone.

Vous vérifiez la documentation. Sérieusement - c'est à ça que ça sert. Vous ne devinez pas ce qu'une fonction fait en fonction de son nom ou de son contexte comme ça. Si vous n'êtes pas sûr et que vous avez accès à son code source, vérifiez-le.

C'est le seul moyen complètement fiable.

Maintenant, pour une estimation gues.

  • S'il accepte un rappel ou renvoie une promesse, il est probablement asynchrone (j'ai vu des exceptions pour cette règle)
  • Généralement, tout ce qui est lié aux E / S dans node.js et plus généralement en JavaScript se fait de manière asynchrone (j'ai également vu des exceptions à cette règle)
Benjamin Gruenbaum
la source
4

Étant donné que JavaScript est un thread unique, tous les blocs de traitement jusqu'à ce que l'un des événements suivants se produise

1) L'exécution actuelle demande un service externe tel qu'une demande d'E / S ou de mise en réseau, ou une demande de webworker

2) Un appel de fonction est placé sur une minuterie pour être exécuté ultérieurement

Il n'y a pas de liste de fonctions bloquantes / non bloquantes. Vous devriez vérifier la documentation.

Votre application peut rencontrer une condition de concurrence critique si plusieurs services externes ont un verrou sur le fil javascript et tentent d'y accéder en même temps. Les navigateurs modernes et le moteur V8 gèrent cela, mais vous pouvez rencontrer cette condition de concurrence si vous utilisez PhoneGap et écrivez des applications javascript pour les appareils mobiles. Le support n'est pas là pour gérer ces conditions de course.

En général, supposez les blocs de code sauf s'il y a un rappel. Et même s'il y a un rappel, cela ne signifie pas qu'il ne se bloquera pas.

codeur
la source
-1

Moi aussi, je suis nouveau sur node.js (et JavaScript en général) et je ne suis pas habitué à autant de code asynchrone. Je voulais juste souligner que dans l' aperçu du blocage contre le non-blocage sur nodejs.org, il indique que:

Toutes les méthodes d'E / S de la bibliothèque standard Node.js fournissent des versions asynchrones non bloquantes et acceptent les fonctions de rappel. Certaines méthodes ont également des équivalents bloquants, dont le nom se termine par Sync.

TaborKelly
la source
1
comment cela répond-il à la question posée? Voir Comment répondre
moucher