Odpowiedzi:
Najłatwiej jest po prostu wywołać tę funkcję bezpośrednio za pierwszym razem:
foo();
setInterval(foo, delay);
Istnieją jednak dobre powody, aby tego unikać setInterval
- w szczególności w niektórych okolicznościach cały szereg setInterval
zdarzeń może nadejść natychmiast po sobie bez żadnych opóźnień. Innym powodem jest to, że jeśli chcesz zatrzymać pętlę, musisz jawnie wywołać, clearInterval
co oznacza, że musisz pamiętać uchwyt zwrócony z pierwotnego setInterval
wywołania.
Zatem alternatywną metodą jest foo
wyzwalanie się dla kolejnych wywołań za pomocą setTimeout
:
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
Gwarantuje to, że między rozmowami jest co najmniej przerwa delay
. Ułatwia także anulowanie pętli w razie potrzeby - po prostu nie dzwoniszsetTimeout
gdy warunek zakończenia pętli zostanie osiągnięty.
Co więcej, możesz zawinąć to wszystko w bezpośrednio wywoływane wyrażenie funkcyjne, które tworzy funkcję, która następnie wywołuje się ponownie jak wyżej i automatycznie uruchamia pętlę:
(function foo() {
...
setTimeout(foo, delay);
})();
który definiuje funkcję i rozpoczyna cykl od razu.
setTimeout
?
setInterval
zdarzeń może nadejść natychmiast po sobie bez żadnych opóźnień.
setTimeout
metody?
Nie jestem pewien, czy rozumiem cię poprawnie, ale możesz łatwo zrobić coś takiego:
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
Jest na to oczywiście wiele sposobów, ale to najbardziej zwięzły sposób, jaki mogę wymyślić.
arguments.callee
nie jest dostępny w ścisłym trybie ES5
Natknąłem się na to pytanie z powodu tego samego problemu, ale żadna z odpowiedzi nie pomaga, jeśli musisz zachowywać się dokładnie tak samo,setInterval()
ale z jedynym różnicą, że funkcja nazywa się natychmiast na początku.
Oto moje rozwiązanie tego problemu:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
Zaletą tego rozwiązania:
setInterval
może być łatwo dostosowany przez podstawienieclearInterval()
późniejPrzykład:
// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
console.log('hello');
}, 1000);
// clear interval after 4.5 seconds
setTimeout( _ => {
clearInterval(myInterval);
}, 4500);
Aby być zuchwałym, jeśli naprawdę potrzebujesz użyć, setInterval
możesz również zastąpić oryginał setInterval
. Dlatego podczas dodawania tego kodu przed istniejącym kodem nie jest wymagana zmiana kodu:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
Nadal obowiązują tutaj wszystkie wymienione wyżej korzyści, ale nie jest wymagana zamiana.
setTimeout
rozwiązania, ponieważ zwraca setInterval
obiekt. Aby uniknąć wywoływania funkcji, które mogą być później w kodzie i dlatego nie są zdefiniowane w chwili obecnej, zawijam pierwsze wywołanie funkcji w setTimeout
funkcji takiej jak ta: setTimeout(function(){ func();},0);
Pierwsza funkcja jest następnie wywoływana po bieżącym cyklu przetwarzania, który jest również natychmiastowy , ale jest więcej potwierdzonych błędów.
Możesz owinąć setInterval()
funkcję, która zapewnia takie zachowanie:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
... użyj tego w następujący sposób:
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
Oto opakowanie na całkiem fajny, jeśli go potrzebujesz:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
Ustaw trzeci argument setInterval na true, a po raz pierwszy uruchomi się natychmiast po wywołaniu setInterval:
setInterval(function() { console.log("hello world"); }, 5000, true);
Lub pomiń trzeci argument, a on zachowa swoje pierwotne zachowanie:
setInterval(function() { console.log("hello world"); }, 5000);
Niektóre przeglądarki obsługują dodatkowe argumenty dla setInterval, których to opakowanie nie bierze pod uwagę; Myślę, że są one rzadko używane, ale pamiętaj o tym, jeśli ich potrzebujesz.
Ktoś musi wprowadzić to, co zewnętrzne, this
jakby to była funkcja strzałki.
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
Jeśli przeszkadzają ci powyższe śmieci, możesz zamiast tego zrobić zamknięcie.
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
A może rozważyć korzystanie z @autobind
dekorator w zależności od kodu.
Zasugeruję wywołanie funkcji w następującej kolejności
var _timer = setInterval(foo, delay, params);
foo(params)
Możesz również przekazać _timer
foo, jeśli chcesz clearInterval(_timer)
pod pewnym warunkiem
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
Oto prosta wersja dla nowicjuszy bez całego zamieszania. Po prostu deklaruje funkcję, wywołuje ją, a następnie rozpoczyna interwał. Otóż to.
//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 );
Jest wygodny pakiet npm o nazwie firstInterval (pełne ujawnienie, to moje).
Wiele przykładów tutaj nie obejmuje obsługi parametrów, a zmiana domyślnych zachowań setInterval
w każdym dużym projekcie jest zła. Z dokumentów:
Ten wzór
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
jest identyczny z
firstInterval(callback, 1000, p1, p2);
Jeśli jesteś starą szkołą w przeglądarce i nie chcesz zależności, możesz łatwo wyciąć i wkleić kod.
// 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, to jest takie skomplikowane, więc powiem bardziej prościej:
function hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
Możesz ustawić bardzo mały początkowy czas opóźnienia (np. 100) i ustawić go na żądany czas opóźnienia w funkcji:
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
Wystąpił problem z natychmiastowym asynchronicznym wywołaniem funkcji, ponieważ standardowy setTimeout / setInterval ma minimalny limit czasu około kilku milisekund, nawet jeśli bezpośrednio ustawisz na 0. Jest to spowodowane pracą przeglądarki.
Przykład kodu z PRAWDZIWYM opóźnieniem zerowym, które działa w Chrome, Safari, Opera
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
Więcej informacji znajdziesz tutaj
Po pierwszym ręcznym wywołaniu możesz utworzyć interwał za pomocą swojej funkcji.
w rzeczywistości najszybsze jest do zrobienia
interval = setInterval(myFunction(),45000)
wywoła to moją funkcję, a następnie zrobi to agaian co 45 sekund, co różni się od działania
interval = setInterval(myfunction, 45000)
który tego nie nazwie, ale tylko zaplanuj
myFunction()
gdy sam się zwraca. Zamiast tego modyfikowanie każdej wywoływanej przez setInterval
nią funkcji jest lepszym podejściem do zawijania, setInterval
gdy proponowane są inne odpowiedzi.
function
raz, a następnie wykonaćsetInterval()