Відповіді:
Найпростіше просто зателефонувати безпосередньо в функцію самостійно:
foo();
setInterval(foo, delay);
Однак є вагомі причини, яких слід уникати setInterval
- зокрема, за деяких обставин, цілий набір setInterval
подій може прийти негайно один за одним без жодних затримок. Ще одна причина полягає в тому, що якщо ви хочете зупинити цикл, вам потрібно чітко зателефонувати, а clearInterval
це означає, що ви повинні запам'ятати ручку, повернуту з початкового setInterval
виклику.
Отже, альтернативним методом є створення foo
тригера для наступних дзвінків, використовуючи setTimeout
замість цього:
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
Це гарантує наявність принаймні інтервалу delay
між дзвінками. Це також спрощує скасування циклу, якщо це потрібно - ви просто не дзвоните, setTimeout
коли буде досягнуто умови завершення циклу.
А ще краще, ви зможете обернути це все виразу функції, що викликається функцією, яка створює функцію, яка потім викликає себе знову, як вище, і автоматично запускає цикл:
(function foo() {
...
setTimeout(foo, delay);
})();
яка визначає функцію і запускає цикл все за один раз.
setTimeout
?
setInterval
подій може прийти негайно один за одним без жодної затримки.
setTimeout
метод?
Я не впевнений, чи правильно я вас розумію, але ви могли легко зробити щось подібне:
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
Очевидно, існує будь-яка кількість способів зробити це, але це найбільш стислий спосіб, який я можу придумати.
arguments.callee
недоступний у суворому режимі
Я натрапив на це питання в зв'язку з тією ж проблемою , але жоден з відповідей не допомагає , якщо вам потрібно вести себе так само , як , setInterval()
але з єдиною різницею , що функція викликається безпосередньо на самому початку.
Ось моє рішення цієї проблеми:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
Перевага цього рішення:
setInterval
легко може бути адаптований за допомогою підстановкиclearInterval()
пізнішеПриклад:
// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
console.log('hello');
}, 1000);
// clear interval after 4.5 seconds
setTimeout( _ => {
clearInterval(myInterval);
}, 4500);
Щоб бути сміливим, якщо вам справді потрібно користуватися, setInterval
тоді ви також можете замінити оригінал setInterval
. Отже, не потрібно змінювати код при додаванні цього до наявного коду:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
Однак усі переваги, перелічені вище, застосовуються тут, але заміни не потрібно.
setTimeout
рішенням, оскільки воно повертає setInterval
об'єкт. Щоб уникнути виклику функцій, які, можливо, пізніше знаходяться в коді і тому не визначені в поточний час, я запускаю перший виклик функції у setTimeout
функцію, як ця: setTimeout(function(){ func();},0);
Перша функція викликається після поточного циклу обробки, який також негайно , але є більше помилок доведено.
Ви можете зафіксувати setInterval()
функцію, яка забезпечує таку поведінку:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
... тоді використовуйте його так:
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
Ось обгортка, щоб її добре переконати, якщо вона вам потрібна:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
Встановіть третій аргумент setInterval на true і він запуститься вперше відразу після виклику setInterval:
setInterval(function() { console.log("hello world"); }, 5000, true);
Або пропустіть третій аргумент, і він збереже свою первісну поведінку:
setInterval(function() { console.log("hello world"); }, 5000);
Деякі браузери підтримують додаткові аргументи для setInterval, які ця обгортка не враховує; Я думаю, що вони рідко використовуються, але майте це на увазі, якщо вони вам потрібні.
Для когось потрібно піднести зовнішнє this
всередину так, ніби це функція стрілки.
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
Якщо вищезгадане виробництво сміття вас турбує, ви можете замість цього зробити закриття.
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
Або , може бути , розглянути можливість використання в @autobind
декоратора в залежності від вашого коду.
Я запропоную викликати функції у наступній послідовності
var _timer = setInterval(foo, delay, params);
foo(params)
Ви також можете передати " _timer
foo", якщо хочете clearInterval(_timer)
за певної умови
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
Ось проста версія для новачків без усіх возитися. Він просто оголошує функцію, викликає її, а потім запускає інтервал. Це воно.
//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 );
Є зручний пакет npm під назвою firstInterval (повне розкриття, це моє).
Багато прикладів тут не включають обробку параметрів, а зміна поведінки за замовчуванням setInterval
у будь-якому великому проекті є злом. З документів:
Ця закономірність
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
тотожна
firstInterval(callback, 1000, p1, p2);
Якщо ви старі школи в браузері і не хочете залежності, це просто вирізати і вставити з коду.
// 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);
Ок, це так складно, тож дозвольте сказати простіше:
function hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
Ви можете встановити дуже невеликий початковий час затримки (наприклад, 100) і встановити його бажаний час затримки в межах функції:
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
Виникла проблема з негайним асинхронним викликом вашої функції, оскільки стандартний setTimeout / setInterval має мінімальний час очікування приблизно кілька мілісекунд, навіть якщо ви безпосередньо встановите його на 0. Це викликано роботою, пов’язаною з браузером.
Приклад коду з РЕАЛЬНОЮ нульовою затримкою, який працює в Chrome, Safari, Opera
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
Ви можете знайти більше інформації тут
І після першого ручного дзвінка ви можете створити інтервал зі своєю функцією.
насправді це найшвидше зробити
interval = setInterval(myFunction(),45000)
це зателефонує моїй функції, а потім робитиме її агайською кожні 45 секунд, що відрізняється від виконання
interval = setInterval(myfunction, 45000)
яка не називатиме її, а запланувати лише її
myFunction()
повернеться. Замість того, щоб змінювати кожну функцію, яку setInterval
вона викликає, краще підходити до завершення setInterval
одного разу, як пропонують інші відповіді.
function
один раз, а потім зробитиsetInterval()