Respostas:
É mais simples chamar a função diretamente diretamente na primeira vez:
foo();
setInterval(foo, delay);
No entanto, existem boas razões para evitar setInterval
- em particular em algumas circunstâncias, uma grande quantidade de setInterval
eventos pode chegar imediatamente um após o outro, sem demora. Outro motivo é que, se você deseja interromper o loop, deve ligar explicitamente, o clearInterval
que significa que é necessário lembrar o identificador retornado da setInterval
chamada original .
Portanto, um método alternativo é foo
acionar-se para chamadas subseqüentes usando setTimeout
:
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
Isso garante que haja pelo menos um intervalo delay
entre as chamadas. Isso também facilita o cancelamento do loop, se necessário - você não liga setTimeout
quando a condição de encerramento do loop é atingida.
Melhor ainda, você pode agrupar tudo isso em uma expressão de função chamada imediatamente que cria a função, que então se chama novamente como acima, e inicia automaticamente o loop:
(function foo() {
...
setTimeout(foo, delay);
})();
que define a função e inicia o ciclo de uma só vez.
setTimeout
?
setInterval
eventos pode chegar imediatamente um após o outro, sem demora.
setTimeout
método?
Não tenho certeza se estou entendendo corretamente, mas você poderia facilmente fazer algo assim:
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
Obviamente, existem várias maneiras de fazer isso, mas é a maneira mais concisa em que consigo pensar.
arguments.callee
não está disponível no modo estrito ES5
Eu me deparei com essa pergunta devido ao mesmo problema, mas nenhuma das respostas ajuda se você precisar se comportar exatamente como o normal,setInterval()
mas com a única diferença de que a função é chamada imediatamente no início.
Aqui está a minha solução para este problema:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
A vantagem desta solução:
setInterval
pode ser facilmente adaptado por substituiçãoclearInterval()
mais tardeExemplo:
// 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 atrevido, se você realmente precisar usar setInterval
, também poderá substituir o original setInterval
. Portanto, nenhuma alteração de código é necessária ao adicionar isso antes do código existente:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
Ainda assim, todas as vantagens listadas acima se aplicam aqui, mas nenhuma substituição é necessária.
setTimeout
solução porque ela retorna um setInterval
objeto. Para evitar chamar funções que talvez estejam mais tarde no código e, portanto, indefinidas no momento atual, envolvo a primeira chamada de função em uma setTimeout
função como esta: setTimeout(function(){ func();},0);
A primeira função é chamada após o ciclo de processamento atual, que também é imediato , mas é mais erros comprovados.
Você pode agrupar setInterval()
uma função que fornece esse comportamento:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
... então use-o assim:
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
Aqui está um invólucro para analisá-lo, se você precisar:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
Defina o terceiro argumento de setInterval como true e ele será executado pela primeira vez imediatamente após chamar setInterval:
setInterval(function() { console.log("hello world"); }, 5000, true);
Ou omita o terceiro argumento e ele manterá seu comportamento original:
setInterval(function() { console.log("hello world"); }, 5000);
Alguns navegadores suportam argumentos adicionais para setInterval que esse wrapper não leva em consideração; Penso que estes raramente são utilizados, mas tenha isso em mente se você precisar deles.
Para alguém precisa trazer o exterior para this
dentro como se fosse uma função de seta.
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
Se o lixo produzido acima o incomoda, você pode fazer um fechamento.
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
Ou talvez considere usar o @autobind
decorador, dependendo do seu código.
Vou sugerir a chamada das funções na seguinte sequência
var _timer = setInterval(foo, delay, params);
foo(params)
Você também pode passar _timer
para o foo, se quiser clearInterval(_timer)
em uma determinada condição
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
Aqui está uma versão simples para iniciantes, sem toda a confusão. Apenas declara a função, chama e depois inicia o intervalo. É isso aí.
//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 );
Existe um pacote npm conveniente chamado firstInterval (divulgação completa, é meu).
Muitos dos exemplos aqui não incluem manipulação de parâmetros, e alterar comportamentos padrão de setInterval
qualquer projeto grande é ruim. Dos documentos:
Esse padrão
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
é idêntico a
firstInterval(callback, 1000, p1, p2);
Se você é da velha escola no navegador e não quer a dependência, é fácil copiar e colar do 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, isso é tão complexo, então, deixe-me simplificar:
function hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
Você pode definir um atraso inicial muito pequeno (por exemplo, 100) e configurá-lo para o atraso desejado na função:
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
Há um problema com a chamada assíncrona imediata de sua função, porque o setTimeout / setInterval padrão tem um tempo limite mínimo de vários milissegundos, mesmo que você o defina diretamente como 0. Isso foi causado por um trabalho específico do navegador.
Um exemplo de código com um atraso zero REAL que funciona no Chrome, Safari, Opera
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
Você pode encontrar mais informações aqui
E após a primeira chamada manual, você pode criar um intervalo com sua função.
na verdade, o mais rápido é fazer
interval = setInterval(myFunction(),45000)
isso chamará de função e, em seguida, fará isso de novo a cada 45 segundos, o que é diferente de fazer
interval = setInterval(myfunction, 45000)
que não vai chamar, mas agendar apenas
myFunction()
retornar automaticamente. Em vez disso, modificar cada função a ser chamada por setInterval
ela é uma abordagem melhor para agrupar setInterval
uma vez, como as outras respostas estão propondo.
function
uma vez e depois fazer osetInterval()