在运行时更改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。

那么,如何在每次匿名函数运行时调整间隔呢?

使用setTimeout()来代替。 然后回调将负责启动下一个超时,在这一点上,你可以增加或以其他方式操纵时间。

编辑

下面是一个通用函数,可以用来为任何函数调用应用“减速”超时。

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

更新:正如A.Wolff所建议的,使用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); 

这可以启动,但你想要的。 超时是我用来保持在一小时之内的方法。

我每小时都需要开始一小时的代码块。 所以这将在服务器启动时开始,每小时运行一次。 基本上,最初的运行是在同一分钟内开始间隔。 所以,在一秒钟内,立即运行,然后每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> 

如果您希望计数器在页面加载后开始增加,请在countingSpeed调用之前将counter1()counter2()放在foo() 。 否则,执行前需要几毫秒的时间。 编辑:更短的答案。

简单的答案是你不能更新已经创建的定时器的时间间隔 。 (只有两个函数setInterval/setTimerclearInterval/clearTimer ,所以有一个timerId你只能停用它。)但是你可以做一些解决方法。 看看这个github回购 。

 var counter = 15; var interval = setTimeout(function(){ // your interval code here window.counter = dynamicValue; interval(); }, counter); 

我是一个JavaScript的初学者,并没有找到任何帮助,在以前的答案(但许多好主意)。
下面这段代码加速(加速度> 1)或减速(加速度<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 :以ms为单位的setInterval初始值(增加或减少)
  • refresh :计算新的timer值之前的时间。 这是步长
  • factor :老的和下一个timer值之间的差距。 这是台阶高度