Esegui la funzione setInterval senza ritardo la prima volta

C’è un modo per configurare il metodo setInterval di javascript per eseguire immediatamente il metodo e poi eseguito con il timer

È più semplice chiamare la funzione direttamente la prima volta:

 foo(); setInterval(foo, delay); 

Tuttavia ci sono buone ragioni per evitare setInterval – in particolare in alcune circostanze un intero carico di eventi setInterval può arrivare immediatamente uno dopo l’altro senza alcun ritardo. Un altro motivo è che se si desidera arrestare il ciclo, è necessario chiamare esplicitamente clearInterval che significa che è necessario ricordare l’handle restituito dalla chiamata setInterval originale.

Quindi un metodo alternativo è quello di avere foo innesca per le chiamate successive utilizzando setTimeout invece:

 function foo() { // do stuff // ... // and schedule a repeat setTimeout(foo, delay); } // start the cycle foo(); 

Ciò garantisce che vi sia almeno un intervallo di delay tra le chiamate. Inoltre, rende più semplice l’annullamento del ciclo, se necessario; basta non chiamare setTimeout quando viene raggiunta la condizione di terminazione del ciclo.

Meglio ancora, puoi racchiuderlo tutto in un’espressione di funzione immediatamente invocata che crea la funzione, che quindi richiama se stessa come sopra, e avvia automaticamente il ciclo:

 (function foo() { ... setTimeout(foo, delay); })(); 

che definisce la funzione e avvia il ciclo tutto in una volta.

Non sono sicuro se sto capendo correttamente, ma potresti facilmente fare qualcosa del genere:

 setInterval(function hello() { console.log('world'); return hello; }(), 5000); 

Ovviamente c’è un qualsiasi numero di modi per farlo, ma questo è il modo più conciso che riesco a pensare.

Ecco un involucro per farla bella se ne hai bisogno:

 (function() { var originalSetInterval = window.setInterval; window.setInterval = function(fn, delay, runImmediately) { if(runImmediately) fn(); return originalSetInterval(fn, delay); }; })(); 

Imposta il terzo argomento di setInterval su true e verrà eseguito per la prima volta immediatamente dopo aver chiamato setInterval:

 setInterval(function() { console.log("hello world"); }, 5000, true); 

O ometti il ​​terzo argomento e manterrà il suo comportamento originale:

 setInterval(function() { console.log("hello world"); }, 5000); 

Alcuni browser supportano argomenti aggiuntivi per setInterval che questo wrapper non prende in considerazione; Penso che siano usati raramente, ma tienilo a mente se ne hai bisogno.

Mi sono imbattuto in questa domanda a causa dello stesso problema, ma nessuna delle risposte è utile se hai bisogno di comportarti esattamente come setInterval() ma con la sola differenza che la funzione viene chiamata immediatamente all’inizio.

Ecco la mia soluzione a questo problema:

 function setIntervalImmediately(func, interval) { func(); return setInterval(func, interval); } 

Il vantaggio di questa soluzione:

  • il codice esistente utilizzando setInterval può essere facilmente adattato per sostituzione
  • funziona in modalità rigorosa
  • Funziona con funzioni e chiusure con nome già esistenti
  • puoi ancora usare il valore di ritorno e passarlo a clearInterval() più tardi

Esempio:

 // create 1 second interval with immediate execution var myInterval = setIntervalImmediately( _ => { console.log('hello'); }, 1000); // clear interval after 4.5 seconds setTimeout( _ => { clearInterval(myInterval); }, 4500); 

Per essere sfacciato, se hai davvero bisogno di usare setInterval puoi anche sostituire il setInterval originale. Quindi, nessun cambiamento di codice richiesto quando si aggiunge questo prima del codice esistente:

 var setIntervalOrig = setInterval; setInterval = function(func, interval) { func(); return setIntervalOrig(func, interval); } 

Tuttavia, tutti i vantaggi elencati sopra si applicano qui, ma non è necessaria alcuna sostituzione.

È ansible setInterval() wrapping di setInterval() in una funzione che fornisce tale comportamento:

 function instantGratification( fn, delay ) { fn(); setInterval( fn, delay ); } 

… quindi usalo in questo modo:

 instantGratification( function() { console.log( 'invoked' ); }, 3000); 
 // YCombinator function anonymous(fnc) { return function() { fnc.apply(fnc, arguments); return fnc; } } // Invoking the first time: setInterval(anonymous(function() { console.log("bar"); })(), 4000); // Not invoking the first time: setInterval(anonymous(function() { console.log("foo"); }), 4000); // Or simple: setInterval(function() { console.log("baz"); }, 4000); 

Suggerirò di chiamare le funzioni nella seguente sequenza

 var _timer = setInterval(foo, delay, params); foo(params) 

Puoi anche passare il _timer al foo, se vuoi clearInterval(_timer) su una determinata condizione

 var _timer = setInterval(function() { foo(_timer, params) }, delay); foo(_timer, params); 

Per risolvere questo problema, eseguo la funzione una prima volta dopo che la pagina è stata caricata.

 function foo(){ ... } window.onload = function() { foo(); }; window.setInterval(function() { foo(); }, 5000); 

C’è un comodo pacchetto npm chiamato firstInterval (full disclosure, è mio).

Molti degli esempi qui non includono la gestione dei parametri e la modifica dei comportamenti predefiniti di setInterval in qualsiasi progetto di grandi dimensioni è malvagia. Dai documenti:

Questo modello

 setInterval(callback, 1000, p1, p2); callback(p1, p2); 

è identico a

 firstInterval(callback, 1000, p1, p2); 

Se sei una vecchia scuola nel browser e non vuoi la dipendenza, è un semplice copia e incolla dal codice.

Ecco una versione semplice per i principianti senza tutti i problemi. Dichiara solo la funzione, la chiama, quindi avvia l’intervallo. Questo è tutto.

 //Declare your function here function My_Function(){ console.log("foo"); } //Call the function first My_Function(); //Set the interval var interval = window.setInterval( My_Function, 500 ); 

C’è un problema con l’immediata chiamata asincrona della tua funzione, perché setTimeout / setInterval standard ha un timeout minimo di alcuni millisecondi anche se lo imposti direttamente su 0. È causato da un lavoro specifico del browser.

Un esempio di codice con un ritardo zero REALE che funziona in Chrome, Safari, Opera

 function setZeroTimeout(callback) { var channel = new MessageChannel(); channel.port1.onmessage = callback; channel.port2.postMessage(''); } 

Puoi trovare maggiori informazioni qui

E dopo la prima chiamata manuale puoi creare un intervallo con la tua funzione.

in realtà il più veloce è da fare

 interval = setInterval(myFunction(),45000) 

questo chiamerà miafunzione, e poi lo farà ogni 45 secondi, che è diverso dal fare

 interval = setInterval(myfunction, 45000) 

che non lo chiamerà, ma lo programmerà solo