10
votes

JavaScript: voie non bloquante d'attendre qu'une condition soit vraie

J'ai plusieurs ASP.NET UpdatePanels, chacun avec un AsyncPostBackTrigger lié à l'événement click Serverside du même bouton. Comme une seule UpdatePanel peut être faire sa chose à la fois, je l'utilise .get_isInAsyncPostBack () du PageRequestManager pour empêcher un utilisateur de pouvoir accéder à une autre partie de la page jusqu'à ce que le postback async est terminée.

Une autre partie de cette page a besoin de mettre à jour dynamiquement des panneaux de mise à jour plusieurs consécutivement. Étant donné que les panneaux de mise à jour utilisent async déclencheurs, appeler __ doPostBack ( "<% = ButtonName.ClientID%>", 'PanelId'); feux asynchonously. À cause de cela, il se déplace rapidement le long de la prochaine itération de la boucle et essayer de mettre à jour le tableau suivant. Cependant, la deuxième itération échoue parce qu'il ya déjà un autre panneau de mise à jour faire un postback async.

Idéalement, il y aurait un moyen d'attendre jusqu'à ce que .get_isInAsyncPostBack () renvoie false sans bloquer toute autre activité du client.

La recherche m'a conduit à beaucoup de gens avec mon problème, dont presque tous sont invités à utiliser setTimeOut () . Je ne suis pas chose cela fonctionne pour moi. Je ne veux pas attendre un certain laps de temps avant d'exécuter une fonction. Je veux simplement mon Javascript d'attendre, tandis qu'un autre script est en cours d'exécution, attendez de préférence jusqu'à ce qu'une condition spécifique est vrai.

Je comprends que beaucoup voudront sans doute suggérer que je repenser mon modèle. Il est en fait pas mon modèle, mais celui qui a été remis à notre équipe de développement qui est actuellement un désordre total sous le capot. En raison les délais prescrits, la réécriture du modèle n'est pas une option. La seule option est de faire ce travail. Je pense que si j'avais un moyen de rendre le code client attente sans bloquer, mon problème serait résolu.


3 commentaires

Ce n'est tout simplement pas la fonction de JavaScript. Il exécutera tout le code de manière synchrone. Html5s cool nouveau Les travailleurs du Web pourraient aider, mais pour le reste que vous " ll n'a pas d'autre choix que d'utiliser settimeout / setInterval .


Bonne question.J'ai trouvé quand j'essaye deux écrire un.


Actuellement, peut-être qu'un meilleur moyen de résoudre ces problèmes serait d'utiliser un travailleur Web pour attendre la réponse côté serveur.


4 Réponses :


34
votes

Il n'y a pas de telles fonctionnalités telles que l'attente ou la sommeil en JavaScript, car elle empêcherait le navigateur de répondre.

Dans votre cas, j'irais avec quelque chose de similaire à suivre: P>

function wait(){
  if (!condition){
    setTimeout(wait,100);
  } else {
    // CODE GOES IN HERE
  }
}


5 commentaires

Je ne sais pas comment cela est censé travailler. Quand j'exécute ce code settimeout (fonction () {alerte ("attente");}, 5000); Alerte ("Donewaiting"); , "Donewaiting" est alerté en premier, suivi de "attente" 5 secondes plus tard. Quel est le point d'attendre s'il s'agit simplement de déménager immédiatement à la ligne de code suivante?


Le concept de délai défini est différent, il n'arrête pas l'exécution du code, mais exécute le code après un certain temps. Il n'y a aucun moyen (au moins bon) de pauser le script. Vous devrez remplacer ... Le code va ici ... avec la logique doit être exécutée après que la condition soit remplie


Cette technique de "sondage" exécute essentiellement la fonction tous les 100 ms jusqu'à la condition devient vrai . Pour vos besoins, je remplacerais condition ici avec .get_isinasyncpostback () et ... le code va ici ... avec l'appel à Mettez à jour le panneau suivant, suivi d'un attendre pour le panneau suivant. Vous voudrez un nouveau attendre () fonction pour chaque panneau (E.g., waitforpanel1 () , waitforpanel2 () , etc.


Que diriez-vous de la taille maximale de la pile d'appel maximale JavaScript?


@pylover en utilisant Settimeout ne doit pas affecter la pile d'appels car elle n'exblique pas à nouveau la fonction qu'après la fin de la fonction actuelle. Il est possible de le faire faux. Je vais ajouter une réponse pour couvrir cela.



14
votes

Il est facile de faire une erreur lors de l'appelant Settimeout qui provoquera la remplissage de la pile d'appels JavaScript. Si votre fonction a des paramètres, vous devez passer à ceux-ci à la fin de la liste de paramètres de paramètre Settimeout comme suit: xxx

si vous passez des paramètres ou même d'inclure vide ( ) Après le nom de la fonction, il sera exécuté immédiatement et remplissez la pile. xxx


0 commentaires

2
votes

Cette fonction appelle Condfunk qui devrait retourner vrai lorsque la condition est remplie. Quand cela se passe-t-il est appelé. CheckInterval Définit le taux de vérification en millisecondes

       wait(
            function() { return new Date().getSeconds() == 10; }, 
            function() { console.log("Done"); },
            100
        );


0 commentaires

6
votes

J'avais besoin de ralentir un processus et j'ai trouvé une petite méthode utile. XXX PRE>

et vous pouvez l'utiliser comme ceci. P>

doWork = async() => {
   if(await this.wait(3)) {
       // After 3 seconds do something...
   }
}


1 commentaires

Ceci est un moyen non bloquant d'attendre sans avoir besoin d'un appel récursif. Je l'aime bien.