Выполнить функцию setInterval без задержки в первый раз - PullRequest
283 голосов
/ 14 июля 2011

Это способ настроить setInterval метод javascript для немедленного выполнения метода и последующего выполнения с таймером

Ответы [ 13 ]

448 голосов
/ 14 июля 2011

Проще всего просто вызвать функцию непосредственно в первый раз:

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);
})();

, который определяет функцию и запускает цикл все за один раз.

181 голосов
/ 14 июля 2011

Я не уверен, правильно ли я вас понимаю, но вы легко могли бы сделать что-то вроде этого:

setInterval(function hello() {
  console.log('world');
  return hello;
}(), 5000);

Очевидно, существует множество способов сделать это, но это самый лаконичный способЯ могу думать о.

10 голосов
/ 13 апреля 2016

Я наткнулся на этот вопрос из-за той же проблемы, но ни один из ответов не поможет, если вам нужно вести себя точно подобно setInterval(), но с разницей only в том, что функция звонил сразу в начале.

Вот мое решение этой проблемы:

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);
}

Тем не менее, все перечисленные выше преимущества применимы здесь, но замена не требуется.

6 голосов
/ 10 апреля 2013

Вот обертка для симпатичной игры, если вам это нужно:

(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, которые эта оболочка не учитывает;Я думаю, что они редко используются, но имейте это в виду, если они вам нужны.

6 голосов
/ 14 июля 2011

Вы можете обернуть setInterval() в функцию, которая обеспечивает такое поведение:

function instantGratification( fn, delay ) {
    fn();
    setInterval( fn, delay );
}

... тогда используйте это так:

instantGratification( function() {
    console.log( 'invoked' );
}, 3000);
2 голосов
/ 10 января 2019

Если кому-то нужно перенести внешний this внутрь, как если бы это была функция стрелки.

(function f() {
    this.emit("...");
    setTimeout(f.bind(this), 1000);
}).bind(this)();

Если вышеописанный мусор вас беспокоит, вы можете вместо этого сделать закрытие.

(that => {
    (function f() {
        that.emit("...");
        setTimeout(f, 1000);
    })();
})(this);

Или, возможно, рассмотрите возможность использования @autobind декоратора в зависимости от вашего кода.

1 голос
/ 24 марта 2017

Я предложу вызывать функции в следующей последовательности

var _timer = setInterval(foo, delay, params);
foo(params)

Вы также можете передать _timer в foo, если вы хотите clearInterval(_timer) для определенногосостояние

var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
1 голос
/ 28 марта 2016

// 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);
0 голосов
/ 31 июля 2018

Вот простая версия для новичков без всего бездельничающего.Он просто объявляет функцию, вызывает ее, затем запускает интервал.Вот и все.

//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 );
0 голосов
/ 06 апреля 2018

Существует удобный пакет npm, называемый firstInterval (полное раскрытие, он мой).

Многие из приведенных здесь примеров не включают обработку параметров, и изменение поведения по умолчанию setInterval в любом крупном проекте - зло. Из документов:

Этот шаблон

setInterval(callback, 1000, p1, p2);
callback(p1, p2);

идентичен

firstInterval(callback, 1000, p1, p2);

Если вы используете старую школу в браузере и не хотите зависимости, это просто вырезать и вставить из кода.

...