Подтвердить что ты не робот

JavaScript: Как получить setInterval() для начала?

Я использую функцию setInterval() для вызова функции каждые 20 секунд. Тем не менее, я заметил, что в первый раз setInterval() на самом деле вызывает функцию через 20 секунд (а не при вызове setInterval()). Вот мое текущее решение:

dothis();
var i = setInterval(dothis, 20000);

Есть ли способ достичь этого, не имея этого дублирующего кода?

4b9b3361

Ответ 1

Ваш метод - это нормальный способ сделать это.

Если это повторяется снова и снова, вы можете сделать функцию утилиты, которая сначала выполнила бы обработчик, а затем установила интервал:

function setIntervalAndExecute(fn, t) {
    fn();
    return(setInterval(fn, t));
}

Затем в вашем коде вы могли бы просто сделать это:

var i = setIntervalAndExecute(dothis, 20000);

Ответ 2

Вы можете сделать анонимную функцию и сразу вызвать ее, за исключением того, что вместо setInterval используется функция setTimeout.

(function doStuff() {
    //Do Stuff Here
    setTimeout(doStuff,20000);
})();

Это приведет к выполнению функции, а затем вызовет ее через 20 секунд.

Обратите внимание, что в зависимости от поведения, которое вы желаете или в некоторых случаях для производительности, лучше использовать setTimeout над setInterval. Основное различие заключается в том, что setInterval вызывает эту функцию всякий раз, когда этот тайм-аут вверх, REGARDLESS, если последний вызов завершил выполнение или произошла ошибка. Используя setTimeout, этот способ гарантирует, что функция завершит свое выполнение до сброса таймера. Многие компромиссы довольно очевидны, но хорошо иметь в виду, когда вы разрабатываете свое приложение.

РЕДАКТИРОВАТЬ В ответ на обеспокоенность Патрика dw о необходимости отмены таймаута. Лучшее решение - не использовать анонимную функцию и просто вызвать ее после объявления

var timeout;
function doStuff() {
    //doStuff 
    timeout = setTimeout(doStuff,20000);
}
doStuff()

Да, это похоже на то, что OP пытался избежать, но он устраняет необходимость вызова функции, а затем вызывает функцию setInterval, поэтому вы сохраняете строку кода. Вы можете остановить и запустить функцию в любое время:

//Stop it
clearTimeout(timeout);

//Start it
doStuff();

Ответ 3

Если ваша функция dothis не нуждается в другом возвратном значении, вы можете вернуть ее.

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

function dothis() {
    // your code
    return dothis;
}

var i = setInterval(dothis(), 20000);

В противном случае вы можете расширить Function.prototype, чтобы предоставить функции вызова и возврата всем вашим функциям:

DEMO: http://jsfiddle.net/ZXeUz/

Function.prototype.invoke_assign = function() {
    var func = this,
        args = arguments;
    func.call.apply( func, arguments );
    return function() { func.call.apply( func, args ); };
};

setInterval( dothis.invoke_assign( 'thisArg', 1, 2, 3 ), 20000 );

// thisArg 1 2 3
// thisArg 1 2 3
// thisArg 1 2 3
// ...

Это немного улучшает ситуацию. Он позволяет передавать набор аргументов. Первый аргумент установит значение this вызываемой функции, а остальные аргументы будут переданы как обычные аргументы.

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