Javascript 如何停止 setTimeout 循环?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8443151/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to stop a setTimeout loop?
提问by Gihan Lasita
I'm trying to build a loading indicator with a image sprite and I came up with this function
我正在尝试用图像精灵构建一个加载指示器,我想出了这个功能
function setBgPosition() {
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<numbers.length)
{
setTimeout(run, 200);
}else
{
setBgPosition();
}
}
setTimeout(run, 200);
}
so the out put is looks like this
所以输出看起来像这样
I had to use setBgPosition(); inside else to keep this running in a loop so now my problem is how to stop this loop once I want [load finished]?
我不得不使用 setBgPosition(); 在 else 中保持循环运行,所以现在我的问题是如何在我想要 [加载完成] 时停止这个循环?
回答by T.J. Crowder
setTimeout
returns a timer handle, which you can use to stop the timeout with clearTimeout
.
setTimeout
返回一个计时器句柄,您可以使用它来停止超时clearTimeout
。
So for instance:
所以例如:
function setBgPosition() {
var c = 0,
timer = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c >= numbers.length) {
c = 0;
}
timer = setTimeout(run, 200);
}
timer = setTimeout(run, 200);
return stop;
function stop() {
if (timer) {
clearTimeout(timer);
timer = 0;
}
}
So you'd use that as:
所以你可以把它用作:
var stop = setBgPosition();
// ...later, when you're ready to stop...
stop();
Note that rather than having setBgPosition
call itself again, I've just had it set c
back to 0
. Otherwise, this wouldn't work. Also note that I've used 0
as a handle value for when the timeout isn't pending; 0
isn't a valid return value from setTimeout
so it makes a handy flag.
请注意setBgPosition
,我没有再次调用自己,而是将其设置c
回0
. 否则,这是行不通的。另请注意,我已用作0
超时未挂起时的句柄值;0
不是一个有效的返回值,setTimeout
所以它是一个方便的标志。
This is also one of the (few) places I think you'd be better off with setInterval
rather than setTimeout
. setInterval
repeats. So:
这也是我认为你最好使用setInterval
而不是的(少数)地方之一setTimeout
。setInterval
重复。所以:
function setBgPosition() {
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c >= numbers.length) {
c = 0;
}
}
return setInterval(run, 200);
}
Used like this:
像这样使用:
var timer = setBgPosition();
// ...later, when you're ready to stop...
clearInterval(timer);
All of the above notwithstanding, I'd want to find a way to make setBgPosition
stop things itself, by detecting that some completion condition has been satisfied.
尽管如此,我还是想找到一种方法来使setBgPosition
事情本身停止,通过检测某些完成条件已得到满足。
回答by ThimoKl
I know this is an old question, I'd like to post my approach anyway. This way you don't have to handle the 0 trick that T. J. Crowder expained.
我知道这是一个老问题,无论如何我想发布我的方法。这样你就不必处理 TJ Crowder 解释的 0 把戏。
var keepGoing = true;
function myLoop() {
// ... Do something ...
if(keepGoing) {
setTimeout(myLoop, 1000);
}
}
function startLoop() {
keepGoing = true;
myLoop();
}
function stopLoop() {
keepGoing = false;
}
回答by VALIKHAN
SIMPLIEST WAY TO HANDLE TIMEOUT LOOP
处理超时循环的最简单方法
function myFunc (terminator = false) {
if(terminator) {
clearTimeout(timeOutVar);
} else {
// do something
timeOutVar = setTimeout(function(){myFunc();}, 1000);
}
}
myFunc(true); // -> start loop
myFunc(false); // -> end loop
回答by Neil Essy
You need to use a variable to track "doneness" and then test it on every iteration of the loop. If done == true then return.
您需要使用一个变量来跟踪“完成度”,然后在循环的每次迭代中对其进行测试。如果 done == true 则返回。
var done = false;
function setBgPosition() {
if ( done ) return;
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
if ( done ) return;
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<numbers.length)
{
setTimeout(run, 200);
}else
{
setBgPosition();
}
}
setTimeout(run, 200);
}
setBgPosition(); // start the loop
setTimeout( function(){ done = true; }, 5000 ); // external event to stop loop
回答by Theo
As this is tagged with the extjs tag it may be worth looking at the extjs method: http://docs.sencha.com/extjs/6.2.0/classic/Ext.Function.html#method-interval
由于这是用 extjs 标签标记的,因此可能值得查看 extjs 方法:http: //docs.sencha.com/extjs/6.2.0/classic/Ext.Function.html#method-interval
This works much like setInterval, but also takes care of the scope, and allows arguments to be passed too:
这很像 setInterval,但也负责作用域,并允许传递参数:
function setBgPosition() {
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<numbers.length){
c=0;
}
}
return Ext.Function.interval(run,200);
}
var bgPositionTimer = setBgPosition();
when you want to stop you can use clearInterval
to stop it
当您想停止时,您可以使用clearInterval
来停止它
clearInterval(bgPositionTimer);
An example use case would be:
一个示例用例是:
Ext.Ajax.request({
url: 'example.json',
success: function(response, opts) {
clearInterval(bgPositionTimer);
},
failure: function(response, opts) {
console.log('server-side failure with status code ' + response.status);
clearInterval(bgPositionTimer);
}
});
回答by Pritom
I am not sure, but might be what you want:
我不确定,但可能是你想要的:
var c = 0;
function setBgPosition()
{
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run()
{
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<=numbers.length)
{
setTimeout(run, 200);
}
else
{
Ext.get('common-spinner').setStyle('background-position', numbers[0] + 'px 0px');
}
}
setTimeout(run, 200);
}
setBgPosition();
回答by Bashirpour
var myVar = null;
if(myVar)
clearTimeout(myVar);
myVar = setTimeout(function(){ alert("Hello"); }, 3000);