Изменение интервала SetInterval во время его работы
Я написал функцию javascript, которая использует setInterval для управления строкой каждую десятую секунды для определенного количества итераций.
function timer() {
var section = document.getElementById('txt').value;
var len = section.length;
var rands = new Array();
for (i=0; i<len; i++) {
rands.push(Math.floor(Math.random()*len));
};
var counter = 0
var interval = setInterval(function() {
var letters = section.split('');
for (j=0; j < len; j++) {
if (counter < rands[j]) {
letters[j] = Math.floor(Math.random()*9);
};
};
document.getElementById('txt').value = letters.join('');
counter++
if (counter > rands.max()) {
clearInterval(interval);
}
}, 100);
};
вместо того, чтобы интервал установлен на определенное число, я хотел бы обновлять его каждый раз, когда он работает, на основе счетчика. Так что вместо:
var interval = setInterval(function() { ... }, 100);
Это было бы что-то вроде:
var interval = setInterval(function() { ... }, 10*counter);
к сожалению, это не работает. Казалось, что" 10 * счетчик " равен 0.
Так, как я могу настроить интервал при каждом запуске анонимной функции?
13 ответов:
использовать
setTimeout()
вместо. Обратный вызов будет отвечать за запуск следующего тайм-аута, в этот момент вы можете увеличить или иным образом управлять временем.EDIT
вот общая функция, которую вы можете использовать для применения таймаута "замедления" для любого вызова функции.
function setDeceleratingTimeout(callback, factor, times) { var internalCallback = function(tick, counter) { return function() { if (--tick >= 0) { window.setTimeout(internalCallback, ++counter * factor); callback(); } } }(times, 0); window.setTimeout(internalCallback, factor); }; // console.log() requires firebug setDeceleratingTimeout(function(){ console.log('hi'); }, 10, 10); setDeceleratingTimeout(function(){ console.log('bye'); }, 100, 10);
вы можете использовать анонимную функцию:
var counter = 10; var myFunction = function(){ clearInterval(interval); counter *= 10; interval = setInterval(myFunction, counter); } var interval = setInterval(myFunction, counter);
обновление: как предложил А. Вольф, используйте
setTimeout
чтобы избежать необходимостиclearInterval
.var counter = 10; var myFunction = function() { counter *= 10; setTimeout(myFunction, counter); } setTimeout(myFunction, counter);
мне нравится этот вопрос-вдохновил маленький объект таймера во мне:
window.setVariableInterval = function(callbackFunc, timing) { var variableInterval = { interval: timing, callback: callbackFunc, stopped: false, runLoop: function() { if (variableInterval.stopped) return; var result = variableInterval.callback.call(variableInterval); if (typeof result == 'number') { if (result === 0) return; variableInterval.interval = result; } variableInterval.loop(); }, stop: function() { this.stopped = true; window.clearTimeout(this.timeout); }, start: function() { this.stopped = false; return this.loop(); }, loop: function() { this.timeout = window.setTimeout(this.runLoop, this.interval); return this; } }; return variableInterval.start(); };
пример использования
var vi = setVariableInterval(function() { // this is the variableInterval - so we can change/get the interval here: var interval = this.interval; // print it for the hell of it console.log(interval); // we can stop ourselves. if (interval>4000) this.stop(); // we could return a new interval after doing something return interval + 100; }, 100); // we can change the interval down here too setTimeout(function() { vi.interval = 3500; }, 1000); // or tell it to start back up in a minute setTimeout(function() { vi.interval = 100; vi.start(); }, 60000);
У меня был тот же вопрос, что и оригинальный плакат, сделал это как решение. Не уверен, насколько это эффективно ....
interval = 5000; // initial condition var run = setInterval(request , interval); // start setInterval as "run" function request() { console.log(interval); // firebug or chrome log clearInterval(run); // stop the setInterval() // dynamically change the run interval if(interval>200 ){ interval = interval*.8; }else{ interval = interval*1.2; } run = setInterval(request, interval); // start the setInterval() }
Это мой способ сделать это, я использую setTimeout:
var timer = { running: false, iv: 5000, timeout: false, cb : function(){}, start : function(cb,iv){ var elm = this; clearInterval(this.timeout); this.running = true; if(cb) this.cb = cb; if(iv) this.iv = iv; this.timeout = setTimeout(function(){elm.execute(elm)}, this.iv); }, execute : function(e){ if(!e.running) return false; e.cb(); e.start(); }, stop : function(){ this.running = false; }, set_interval : function(iv){ clearInterval(this.timeout); this.start(false, iv); } };
использование:
timer.start(function(){ console.debug('go'); }, 2000); timer.set_interval(500); timer.stop();
гораздо проще было бы иметь
if
оператор в обновленной функции и элемент управления для выполнения команды через регулярные промежутки времени . В следующем примере я запускаю предупреждение каждые 2 секунды и интервал (intrv
) могут быть динамически изменены...var i=1; var intrv=2; // << control this variable var refreshId = setInterval(function() { if(!(i%intrv)) { alert('run!'); } i++; }, 1000);
простой ответ:вы не можете обновить интервал уже созданного таймера. (Есть только две функции
setInterval/setTimer
иclearInterval/clearTimer
, поэтомуtimerId
вы можете только отключить его.), Но вы можете сделать некоторые обходные пути. Взгляните на этот GitHub РЕПО.
это может быть инициировано, как вы хотите. тайм-аут-это метод, который я использовал, чтобы держать его в верхней части часа.
у меня была необходимость каждый час, чтобы начать блок кода на час. Так что это начнется при запуске сервера и запустить интервал ежечасно. В основном начальный запуск должен начинаться с интервала в течение той же минуты. Так что через секунду от init, запустить сразу же, то на каждые 5 секунд.
var interval = 1000; var timing =function(){ var timer = setInterval(function(){ console.log(interval); if(interval == 1000){ /*interval you dont want anymore or increment/decrement */ interval = 3600000; /* Increment you do want for timer */ clearInterval(timer); timing(); } },interval); } timing();
поочередно, если вы хотите, чтобы просто что-то произошло в начале и тогда навсегда с определенным интервалом вы можете просто назвать его одновременно с setInterval. Например:
var this = function(){ //do } setInterval(function(){ this() },3600000) this()
здесь у нас есть этот запуск в первый раз, а затем каждый час.
Я не мог синхронизировать и изменить скорость моих setIntervals тоже, и я собирался опубликовать вопрос. Но я думаю, что нашел способ. Это, безусловно, должно быть улучшено, потому что я новичок. Итак, я бы с удовольствием прочитал ваши комментарии/замечания по этому поводу.
<body onload="foo()"> <div id="count1">0</div> <div id="count2">2nd counter is stopped</div> <button onclick="speed0()">pause</button> <button onclick="speedx(1)">normal speed</button> <button onclick="speedx(2)">speed x2</button> <button onclick="speedx(4)">speed x4</button> <button onclick="startTimer2()">Start second timer</button> </body> <script> var count1 = 0, count2 = 0, greenlight = new Boolean(0), //blocks 2nd counter speed = 1000, //1second countingSpeed; function foo(){ countingSpeed = setInterval(function(){ counter1(); counter2(); },speed); } function counter1(){ count1++; document.getElementById("count1").innerHTML=count1; } function counter2(){ if (greenlight != false) { count2++; document.getElementById("count2").innerHTML=count2; } } function startTimer2(){ //while the button hasn't been clicked, greenlight boolean is false //thus, the 2nd timer is blocked greenlight = true; counter2(); //counter2() is greenlighted } //these functions modify the speed of the counters function speed0(){ clearInterval(countingSpeed); } function speedx(a){ clearInterval(countingSpeed); speed=1000/a; foo(); } </script>
если вы хотите, чтобы счетчики начали увеличиваться после загрузки страницы, поместите
counter1()
иcounter2()
наfoo()
доcountingSpeed
называется. В противном случае, это займетspeed
миллисекунды до выполнения. Редактировать: короче ответ.
var counter = 15; var interval = setTimeout(function(){ // your interval code here window.counter = dynamicValue; interval(); }, counter);
Я новичок в JavaScript и не нашла в предыдущих ответах (но много хороших идей).
Этот фрагмент кода ниже ускоряет (ускорение > 1) или замедляет (ускорениеfunction accelerate(yourfunction, timer, refresh, acceleration) { var new_timer = timer / acceleration; var refresh_init = refresh;//save this user defined value if (refresh < new_timer ){//avoid reseting the interval before it has produced anything. refresh = new_timer + 1 ; }; var lastInter = setInterval(yourfunction, new_timer); console.log("timer:", new_timer); function stopLastInter() { clearInterval(lastInter); accelerate(yourfunction, new_timer, refresh_init, acceleration); console.log("refresh:", refresh); }; setTimeout(stopLastInter, refresh); }
С :
timer
: начальное значение setInterval в МС (увеличение или уменьшение)refresh
: время до нового значенияtimer
рассчитывается. Это и есть шаг длинаfactor
: разрыв между старым и следующейtimer
значение. Это и есть шаг высота
(function variableInterval() { //whatever needs to be done interval *= 2; //deal with your interval setTimeout(variableInterval, interval); //whatever needs to be done })();
не может быть короче
создать новую функцию:
// set Time interval $("3000,18000").Multitimeout(); jQuery.fn.extend({ Multitimeout: function () { var res = this.selector.split(","); $.each(res, function (index, val) { setTimeout(function () { //...Call function temp(); }, val); }); return true; } }); function temp() { alert(); }