Maison > Article > interface Web > Parlons des raisons pour lesquelles vous devriez essayer de ne pas utiliser setInterval
Pourquoi essayer de ne pas utiliser setInterval ? L'article suivant abordera brièvement les raisons pour lesquelles vous devriez essayer de ne pas utiliser setInterval. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.
Lors du développement d'un outil de chat en ligne, il est souvent nécessaire d'effectuer une opération de manière répétée après un certain nombre de millisecondes. "Pas de problème", ont dit tout le monde, "utilisez simplement setInterval". Je pense que cette idée est terrible.
Une des raisons : setInterval ignore les erreurs de code
setInterval a la fâcheuse habitude de signaler les erreurs au code qu'il appelle indifférent. En d’autres termes, si le code exécuté par setInterval échoue pour une raison quelconque, il continuera à appeler ce code indépendamment de cela. Regardez le code
function a() { try{ a.error.here; } catch(e){ $('body').append('<div>' + e.toString() + '</div>'); throw e; } } function b() { try{ b.error.here; } catch(e) { $('body').append('<div>' + e.toString() + '</div>'); throw e; } setTimeout(b, 2000); } setInterval(a, 2000); setTimeout(b, 2000);
Deuxième raison : setInterval ignore le délai du réseau
Supposons que vous interrogez le serveur via Ajax de temps en temps, voir Voir s'il y a de nouvelles données (remarque : si vous faites cela, vous le faites probablement mal ; il est recommandé d'utiliser « l'interrogation compensatoire » (interrogation d'interruption) [1]). Et pour certaines raisons (surcharge du serveur, panne temporaire du réseau, augmentation soudaine du trafic, bande passante utilisateur limitée, etc.), votre demande prendra beaucoup plus de temps que vous ne le pensez. Mais setInterval s'en fiche. Il enverra toujours des requêtes régulièrement et, éventuellement, la file d'attente de votre réseau client sera remplie d'appels Ajax. Regardez le code
var n = 0, t = 0, u = 0, i, s = 'Stopping after 25 requests, to avoid killing jsfiddle’s server'; function a() { $.post('/ajax_html_echo/', function () { --n; }); ++n; ++t; $('#reqs').html(n + ' a() requests in progress!'); if (t > 25) { clearInterval(i); $('#reqs').html(s); } } function b() { ++u; $.post('/ajax_html_echo/', function () { $('#req2').html('b(): ' + new Date().toString()); if (u <= 25) { setTimeout(b, 500); } else { $('#req2').html(s); } }); } i = setInterval(a, 500); setTimeout(b, 500);
La troisième raison : setInterval n'est pas garanti d'exécuter
Contrairement à setTimeout, vous ne pouvez pas garantir que le code sera précis lorsque l'intervalle de temps est atteint. Peut être exécuté. Si la fonction que vous appelez prend beaucoup de temps, certains appels seront simplement ignorés. En regardant le code
function slow() { $.ajax({ url: '/echo/html/', async: false, data: { delay: 1 }, complete: function () { } }); $('#reqs').text(~~((new Date() - start) / 100) + ' expected, ' + iters + ' actual'); if (iters++ > 4) { $('#reqs').append('<br>Stopping after 5 iterations'); clearInterval(iv); } }; var iv = setInterval(slow, 100), start = +new Date(), iters = 0;
La solution est simple : utilisez setTimeout
Au lieu d'utiliser setInterval, il est préférable d'appeler la fonction elle-même via setTimeout au moment opportun. Dans les deux exemples précédents, la fonction a utilisant les erreurs setInterval, tandis que la fonction b utilisant setTimeout fonctionne bien.
Et si les intervalles devaient être égaux ?
Si vous voulez vraiment vous assurer que l'événement est déclenché "de manière uniforme", vous pouvez soustraire le temps passé sur le dernier appel du délai souhaité, puis attribuer dynamiquement la différence à setTimeout comme un retard. Cependant, il convient de noter que les timers JavaScript ne sont pas très précis [2]. Vous ne pouvez donc pas obtenir une latence absolument "moyenne", même avec setInterval, pour de nombreuses raisons (garbage collection, JavaScript étant monothread, etc.). De plus, les navigateurs actuels fixeront également le délai d'attente minimum entre 4 ms et 15 ms. Ne vous attendez donc à aucune erreur.
Pour plus de connaissances liées à la programmation, veuillez visiter : Enseignement de la programmation ! !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!