Ответы:
Проще всего просто вызвать функцию самостоятельно в первый раз:
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
недоступен в строгом режиме ES5
Я наткнулся на этот вопрос из-за той же проблемы, но ни один из ответов не поможет, если вам нужно вести себя точно так же, 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)
это вызовет myfunction, а затем будет делать это каждые 45 секунд, что отличается от выполнения
interval = setInterval(myfunction, 45000)
который не будет называть это, но запланировать это только
myFunction()
возвращает себя. Вместо того, чтобы модифицировать каждую функцию, вызываемую setInterval
ею, лучше подходить setInterval
один раз, как предлагают другие ответы.
function
один раз, а затем сделатьsetInterval()