Risposte:
È più semplice chiamare la funzione da soli 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 setInterval
eventi può arrivare immediatamente uno dopo l'altro senza alcun ritardo. Un altro motivo è che se si desidera interrompere il ciclo, è necessario chiamare esplicitamente, il clearInterval
che significa che è necessario ricordare l'handle restituito dalla setInterval
chiamata originale .
Quindi un metodo alternativo è quello di foo
attivarsi per le chiamate successive usando 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 delay
tra le chiamate. Inoltre, rende più semplice l'annullamento del loop, se necessario, semplicemente non si chiamasetTimeout
quando viene raggiunta la condizione di terminazione del loop.
Meglio ancora, puoi concludere tutto in un'espressione di funzione immediatamente invocata che crea la funzione, che quindi si chiama di nuovo come sopra e avvia automaticamente il ciclo:
(function foo() {
...
setTimeout(foo, delay);
})();
che definisce la funzione e avvia il ciclo tutto in una volta.
setTimeout
?
setInterval
eventi può arrivare immediatamente uno dopo l'altro senza alcun ritardo.
setTimeout
metodo?
Non sono sicuro di capirti correttamente, ma potresti facilmente fare qualcosa del genere:
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
Esistono ovviamente molti modi per farlo, ma è il modo più conciso a cui riesco a pensare.
arguments.callee
non è disponibile in modalità ES5 rigorosa
Mi sono imbattuto in questa domanda a causa dello stesso problema, ma nessuna delle risposte aiuta se devi comportarti esattamente come, setInterval()
ma con l' unica 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:
setInterval
può essere facilmente adattato mediante sostituzioneclearInterval()
più tardiEsempio:
// 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 l'originale setInterval
. Pertanto, non è necessario modificare il codice quando si aggiunge questo prima del codice esistente:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
Tuttavia, tutti i vantaggi sopra elencati si applicano qui, ma non è necessaria alcuna sostituzione.
setTimeout
soluzione perché restituisce un setInterval
oggetto. Per evitare di chiamare funzioni che potrebbero essere più avanti nel codice e quindi non definite al momento attuale, avvolgo la prima chiamata di funzione in una setTimeout
funzione come questa: setTimeout(function(){ func();},0);
La prima funzione viene quindi chiamata dopo l'attuale ciclo di elaborazione, che è anche immediatamente , ma è più errore dimostrato.
Potresti avvolgere setInterval()
una funzione che fornisce quel comportamento:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
... quindi usalo in questo modo:
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
Ecco un wrapper per cercarlo abbastanza 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 di cui questo wrapper non tiene conto; Penso che questi vengano usati raramente, ma tienilo a mente se ne hai bisogno.
Perché qualcuno ha bisogno di portare l'esterno this
all'interno come se fosse una funzione freccia.
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
Se la spazzatura che produce sopra ti dà fastidio, puoi invece effettuare una chiusura.
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
O forse considera l'utilizzo del @autobind
decoratore a seconda del tuo codice.
Suggerirò di chiamare le funzioni nella seguente sequenza
var _timer = setInterval(foo, delay, params);
foo(params)
È inoltre possibile passare il _timer
al foo, se si desidera a clearInterval(_timer)
una determinata condizione
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
Ecco una versione semplice per i principianti senza tutto il casino. Dichiara semplicemente 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 comodo pacchetto npm chiamato firstInterval (divulgazione completa, è mio).
Molti degli esempi qui non includono la gestione dei parametri e cambiare i comportamenti predefiniti di setInterval
qualsiasi progetto di grandi dimensioni è male. 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 taglia e incolla dal codice.
// 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);
Ok, questo è così complesso, quindi, lasciami dire più semplice:
function hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
È possibile impostare un ritardo iniziale molto piccolo (ad es. 100) e impostarlo sul ritardo desiderato all'interno della funzione:
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
C'è un problema con la chiamata asincrona immediata della tua funzione, perché setTimeout / setInterval standard ha un timeout minimo di diversi millisecondi anche se lo imposti direttamente a 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 è possibile creare un intervallo con la propria funzione.
in realtà il più veloce è fare
interval = setInterval(myFunction(),45000)
questo chiamerà myfunction, e poi lo farà agaian ogni 45 secondi, il che è diverso dal fare
interval = setInterval(myfunction, 45000)
che non lo chiamerà, ma solo programmarlo
myFunction()
ritorna da solo. Invece, modificare ogni funzione che deve essere chiamata da setInterval
essa è un approccio migliore per concludere setInterval
una volta come le altre risposte propongono.
function
una volta e poi a faresetInterval()