2013-09-23 3 views
0

Je sais que ces types de questions arrivent assez souvent, mais j'ai besoin d'aide avec un mécanisme d'attente en JavaScript. Je sais que des solutions basées sur setTimeout vont arriver, mais je ne suis pas sûr de savoir comment le faire dans mon cas. J'écris une API qui utilise un WebSocket en interne. Il y a une méthode connect() qui configure le WebSocket, et je dois le faire ne pas retourner jusqu'à ce que WebSocket soit configuré. Je voudrais qu'il renvoie une valeur pour savoir si la connexion a réussi ou non, mais ce n'est pas le problème principal.Prévenir le retour jusqu'à ce que la condition soit remplie

Le problème que je rencontre est qu'après qu'un utilisateur appelle connect(), il peut appeler une autre méthode qui repose sur WebSocket pour être correctement configuré. Si elle est appelée trop tôt, une erreur est émise indiquant que l'objet n'est pas utilisable.

Ma solution actuelle est de définir un indicateur "connecté" lorsque j'ai déterminé une connexion réussie et dans chaque méthode la vérifiant dans chaque méthode. S'il n'est pas connecté, j'ajoute l'appel de méthode à une file d'attente qui est parcourue par le même code que celui qui définit l'indicateur. Cela fonctionne, mais il introduit ce style de code partout dans mes méthodes et semble également trompeur du point de vue de l'utilisateur, puisque l'appel de ces fonctions est différé. En outre, s'il existe un autre code utilisateur qui repose sur la fin de ces appels avant qu'il ne les atteigne, il ne se comportera pas comme prévu.

J'ai creusé mon cerveau avec la façon de gérer ce cas. La solution la plus simple consiste à trouver un moyen de bloquer le retour de la connexion jusqu'à la configuration de WebSocket, mais ce n'est pas vraiment la méthode JavaScript. L'autre option était de leur faire fournir le reste de leur code dans un rappel, mais cela semble être une chose étrange à faire dans ce cas. Peut-être que je suis trop penser?

Edit: Pour mieux illustrer mon problème, voici un exemple de ce que l'utilisateur peut faire:

var client = new Client(options); 
client.connect(); 
client.getServerStatus(); 

La méthode getServerStatus() serait à l'aide du WebSocket interne. Si le WebSocket n'est pas encore configuré, l'utilisateur obtiendra cette erreur non utilisable.

+1

qu'en est-il de la désactivation des interruptions d'utilisateur jusqu'à la configuration de la socket Web? C'est la magie d'async javascript, le navigateur a le temps de rafraichir le dom tout en traitant vos requêtes. – Sebas

+0

Que diriez-vous d'essayer d'abord et de poster une question si quelque chose ne va pas? – Sebastien

+0

appelez la "autre méthode" de l'événement de connexion de la socket au lieu de la même place que celle initié par le socket ... – dandavis

Répondre

2

Todays Javascript ne fonctionne pas vraiment comme ça malheureusement. À l'avenir (ECMA6), il se peut que de nouvelles fonctionnalités linguistiques traitent ce problème plus directement. Cependant pour l'instant vous êtes bloqué avec la méthode actuellement acceptée de gestion des événements asynchrones, qui est limitée aux rappels. Vous pouvez également explorer des «promesses» pour gérer «l'enfer du rappel», mais vous aurez besoin d'une bibliothèque pour cela.

Et oui, il semble étrange d'avoir des rappels partout, surtout pour quelqu'un de nouveau à la programmation Web, mais c'est vraiment la seule façon de s'y prendre à ce stade (en supposant que vous voulez une solution compatible avec plusieurs navigateurs).

0

"Attendre" est presque le mot-clé que vous recherchez. En fait, c'est yield qui fait cela. Voir par exemple MDN's documentation.

+0

attention ... le support pour le rendement est limité http://kangax.github.io/ es5-compat-table/es6/# Générateurs (rendement) – neonstalwart

0

Il y a une méthode de connexion() qui met en place le WebSocket, et je dois le faire pas revenir qu'après la WebSocket est mis en place

Cela ne va pas se produire à moins que vous réécrivez la moteur d'exécution javascript. Soit le code essayant d'envoyer des données devra vérifier l'état du socket (je vais encapsuler le socket dans un objet, fournir une méthode qui définit une variable membre sur les événements open/close et interroger l'état de cette variable membre du code externe).Vous pouvez également ajouter des messages et des rappels à une file d'attente et traiter la file d'attente lorsque le socket se connecte.

Questions connexes