Respuestas:
Es más simple llamar a la función usted mismo directamente la primera vez:
foo();
setInterval(foo, delay);
Sin embargo, hay buenas razones para evitar setInterval
: en particular, en algunas circunstancias, una carga completa de setInterval
eventos puede llegar inmediatamente uno después del otro sin demora. Otra razón es que si desea detener el ciclo, debe llamar explícitamente, lo clearInterval
que significa que debe recordar el identificador devuelto por la setInterval
llamada original .
Entonces, un método alternativo es tener un foo
desencadenante para llamadas posteriores usando en su setTimeout
lugar:
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
Esto garantiza que haya al menos un intervalo delay
entre llamadas. También hace que sea más fácil cancelar el ciclo si es necesario: simplemente no llama setTimeout
cuando se alcanza la condición de finalización del ciclo.
Mejor aún, puede envolver todo en una expresión de función invocada de inmediato que crea la función, que luego se llama a sí misma como se indicó anteriormente, y automáticamente inicia el ciclo:
(function foo() {
...
setTimeout(foo, delay);
})();
que define la función y comienza el ciclo todo de una vez.
setTimeout
?
setInterval
eventos puede llegar inmediatamente uno después del otro sin demora.
setTimeout
método?
No estoy seguro si te estoy entendiendo correctamente, pero podrías hacer algo como esto fácilmente:
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
Obviamente, hay varias formas de hacerlo, pero esa es la forma más concisa en la que puedo pensar.
arguments.callee
no está disponible en el modo estricto ES5
Me topé con esta pregunta debido al mismo problema, pero ninguna de las respuestas ayuda si necesita comportarse exactamente igual, setInterval()
pero con la única diferencia de que la función se llama inmediatamente al principio.
Aquí está mi solución a este problema:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
La ventaja de esta solución:
setInterval
puede adaptarse fácilmente mediante sustituciónclearInterval()
tardeEjemplo:
// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
console.log('hello');
}, 1000);
// clear interval after 4.5 seconds
setTimeout( _ => {
clearInterval(myInterval);
}, 4500);
Para ser descarado, si realmente necesita usar setInterval
, también podría reemplazar el original setInterval
. Por lo tanto, no se requiere un cambio de código al agregar esto antes de su código existente:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
Aún así, todas las ventajas enumeradas anteriormente se aplican aquí, pero no es necesaria ninguna sustitución.
setTimeout
solución porque devuelve un setInterval
objeto. Para evitar llamar a funciones que pueden estar más adelante en el código y, por lo tanto, no definidas en el momento actual, envuelvo la primera llamada de función en una setTimeout
función como esta: setTimeout(function(){ func();},0);
la primera función se llama después del ciclo de procesamiento actual, que también es inmediato , pero es Más error probado.
Podría incluir setInterval()
una función que proporcione ese comportamiento:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
... luego úsalo así:
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
Aquí hay un contenedor para personalizarlo si lo necesita:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
Establezca el tercer argumento de setInterval en verdadero y se ejecutará por primera vez inmediatamente después de llamar a setInterval:
setInterval(function() { console.log("hello world"); }, 5000, true);
O omita el tercer argumento y conservará su comportamiento original:
setInterval(function() { console.log("hello world"); }, 5000);
Algunos navegadores admiten argumentos adicionales para setInterval que este contenedor no tiene en cuenta; Creo que estos rara vez se usan, pero tenlo en cuenta si los necesitas.
Para alguien necesita traer el exterior al this
interior como si fuera una función de flecha.
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
Si la producción de basura anterior le molesta, puede hacer un cierre en su lugar.
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
O tal vez considere usar el @autobind
decorador dependiendo de su código.
Sugeriré llamar a las funciones en la siguiente secuencia
var _timer = setInterval(foo, delay, params);
foo(params)
También puede pasar el _timer
mensaje al foo, si lo desea clearInterval(_timer)
en una determinada condición
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
Aquí hay una versión simple para principiantes sin todos los problemas. Simplemente declara la función, la llama y luego comienza el intervalo. Eso es.
//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 );
Hay un conveniente paquete npm llamado firstInterval (divulgación completa, es mío).
Muchos de los ejemplos aquí no incluyen el manejo de parámetros y el cambio de comportamientos predeterminados de setInterval
cualquier proyecto grande es malo. De los documentos:
Este patrón
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
es idéntico a
firstInterval(callback, 1000, p1, p2);
Si eres de la vieja escuela en el navegador y no quieres la dependencia, es un fácil cortar y pegar del código.
// 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, esto es muy complejo, así que déjenme ponerlo más simple:
function hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
Puede establecer un tiempo de retraso inicial muy pequeño (por ejemplo, 100) y establecerlo en el tiempo de retraso deseado dentro de la función:
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
Hay un problema con la llamada asincrónica inmediata de su función, porque setTimeout / setInterval estándar tiene un tiempo de espera mínimo de varios milisegundos, incluso si lo configura directamente a 0. Esto se debe a un trabajo específico del navegador.
Un ejemplo de código con un REAL cero retraso que funciona en Chrome, Safari, Opera
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
Puedes encontrar más información aquí
Y después de la primera llamada manual, puede crear un intervalo con su función.
en realidad lo más rápido es hacer
interval = setInterval(myFunction(),45000)
esto llamará mi función, y luego lo hará de nuevo cada 45 segundos, lo que es diferente de hacerlo
interval = setInterval(myfunction, 45000)
que no lo llamará, pero solo programarlo
myFunction()
se devuelve solo. En cambio, modificar cada función que se llamará por setInterval
él es un mejor enfoque para ajustar setInterval
una vez como lo proponen las otras respuestas.
function
una vez y luego hacer elsetInterval()