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 setIntervaleventi può arrivare immediatamente uno dopo l'altro senza alcun ritardo. Un altro motivo è che se si desidera interrompere il ciclo, è necessario chiamare esplicitamente, il clearIntervalche significa che è necessario ricordare l'handle restituito dalla setIntervalchiamata originale .
Quindi un metodo alternativo è quello di fooattivarsi per le chiamate successive usando setTimeoutinvece:
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
Ciò garantisce che vi sia almeno un intervallo delaytra 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?
setIntervaleventi può arrivare immediatamente uno dopo l'altro senza alcun ritardo.
setTimeoutmetodo?
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.calleenon è 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:
setIntervalpuò 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, setIntervalpuoi 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.
setTimeoutsoluzione perché restituisce un setIntervaloggetto. 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 setTimeoutfunzione 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 thisall'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 @autobinddecoratore 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 _timeral 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 setIntervalqualsiasi 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 setIntervalessa è un approccio migliore per concludere setIntervaluna volta come le altre risposte propongono.
functionuna volta e poi a faresetInterval()