7
votes

JavaScript Settimeout Sortie inattendue

Je travaille avec des scripts utilisant la fonction de seinterval (FN, de retard) dans ma demande et après avoir lu sur la manière dont Settimeout et JS fonctionnent, je rencontre des résultats étranges, donc j'ai fait un test: Voici le jsfiddle https://jsfiddle.net/jyq46uu1/2/

et le code comme suggéré: xxx

OK, de ce que j'ai rouge de http: / /ejohn.org/blog/how-javascript-timers-work/ JavaScript rendez la minuterie d'appels à la fonction de seinterval Même si le "thread est bloqué", donc si la fonction est toujours en cours d'exécution de l'appel. et ainsi de suite, et ainsi de suite ... Dans mon ordinateur portable, le code produit ceci: xxx

OK, si ce que je suis rouge est vrai, au moment où le premier intervalle est terminé , Toutes les fonctions appels étaient dans la file d'attente ... Dans mon script, je réduit le travail de chaque exécution, chaque appel devrait donc prendre moins de secondes que le précédent, mais peu importe la quantité d'itérations que j'ai définies, le temps écoulé toujours, le temps écoulé le rythme d'intervalle après la 4ème course. Peut-être que je me suis trompé, mais si au fil du temps 4264, toutes les fonctions sont déjà dans la file d'attente et sont supposées courir immédiatement, elles devraient montrer moins de temps, non? ... Si la 3ème itération affiche 91 et les autres sont juste derrière elles devraient prendre 91 ou moins. Mais ce n'est pas le cas.

Si vous comprenez ce qui se passe, veuillez me l'expliquer, car je pense que je manque quelque chose.


0 commentaires

3 Réponses :


0
votes

Je ne suis pas sûr que je suis juste sur ceci et c'est sur ce que je sais de "JavaScript".

JavaScript est basé sur le déclenchement basé sur l'événement et il n'y a "pas de file d'attente et attend". Il sera juste d'aller simultanément (quelque chose comme le filetage).

Je suppose que cela aura un sens comme à quel point cela interprétera-t-il et prenant le suivant.


3 commentaires

Pas du tout @Alexander, veuillez lire ici. Stackoverflow.com/Questtions/2734025 / ...


Lisez les commentaires classés sur cette réponse. Un tel comportement ne fait pas de javascript multi-filetés. C'est le comportement de l'hôte lorsque le script appelle l'API environnements, qui peut appeler davantage de votre code avant de retourner au code appelé API. Aucune deux sections de votre code ne s'exécutera jamais en même temps (sans travailleur).


Pretty Aguable, lorsque vous êtes en mesure d'exécuter / appelle simultanément plusieurs scripts. Il n'a pas été appelé à être multi-threading?



1
votes

Je pense que la première fois ne compte pas à partir de l'intervalle initial dans la file d'attente, mais à partir du point où vous définissez StartTime.

La première minuterie comporte le temps d'initialisation, la création d'environnement, les variables et l'allocation de minuterie.

Essayez cette modification: xxx

De plus, la première fois prend plus de temps probablement parce que la fonction est interprétée, les temps suivants sont exécutés "compilés" / optimisé par le JavaScript JIT (voir https://fr.wikipedia.org/wiki/just- In-Time_Compilation ). Consultez ce code pour voir la preuve xxx

la sortie: xxx

setInterval n'est pas bon à mesurer le temps dans lequel Il devrait faire la queue la prochaine exécution. Je pense que cela a à voir avec dormir () ing. Il n'est pas fiable si un processus prend la CPU et le suspend à celui-ci (comme pour vous le faire).

setInterval garantie uniquement ceci:

  • L'exécution numéro 1 ne va pas se passer en moins de 250 ms.
  • L'exécution numéro 2 ne va pas se passer dans moins de 2 * 250 ms à venir.
  • L'exécution numéro 3 ne va pas arriver dans moins de 3 * 250 ms à venir.
  • ...

    Seinterval ne garantit pas qu'une certaine exécution va se passer avant un délai déterminé à l'avenir. Cela dépend de l'utilisation actuelle de la CPU.

    La mise en file d'attente et le lancement des fonctions en file d'attente dépend également de l'utilisation actuelle de la CPU.

    Conseil supplémentaire Si vous avez besoin d'exécuter une fonction périodiquement, je recommande cette approche qui garantit un retard toujours plus grand que 250 ms entre exécutions xxx


7 commentaires

Je suis intrigué sur le deuxième code ... Je ne parviens pas à voir la différence de la première mais la sortie est clairement différente.


@Gabrielmatunesevich starttime = nouvelle date (); en haut de la fonction


J'ai ajouté starttime = nouvelle date (); comme première ligne dans la fonction, pour voir le temps écoulé uniquement pour la fonction, sans effets secondaires dans la mesure de temps de seinterval


Donc, en fait, les fonctions font la queue ... simplement la mesure de temps était fausse?


et le temps de réinitialisation // à la fin de la fonction n'est plus nécessaire


Oui, c'est vrai, mais ne fait pas mal à la preuve. J'ai répondu avec un peu plus de perspicacité.


Merci pour l'explication, il y a des réponses similaires, mais je pense que c'était l'un des premiers et mieux expliqué.



0
votes

Eh bien, j'ai quelques points à parler, voir les résultats en premier.

le code "nouveau": xxx

Notez que je supprimai la variable de démarrage de la ligne 4 et que vous le transmettez au début de la fonction, donc, le calculé Le temps est le même pour tous les appels. J'ai changé le formulaire de minuterie de 250ms à 1 ms, vous n'avez donc pas à calculer -250ms à partir de chaque résultat.

Les nouveaux résultats sont assez cohérents et montrent que les dépenses de temps pour calculer sont très acceptables et cohérentes maintenant.

J'espère que j'ai aidé à le refuser.


0 commentaires