如何停止 setTimeout 循环?
我正在尝试使用图像精灵构建一个加载指示器,并且我想出了这个函数,
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);
}
因此输出看起来像这样
我必须使用 setBgPosition();在 else 内部保持循环运行,所以现在我的问题是一旦我想要[加载完成]如何停止这个循环?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
setTimeout
返回一个计时器句柄,您可以使用它来通过clearTimeout
停止超时。因此,例如:
所以您可以将其用作:
请注意,我没有让
setBgPosition
再次调用自身,而是将其设置为c
回0
。否则,这行不通。另请注意,我使用0
作为超时未挂起时的句柄值;0
不是setTimeout
的有效返回值,因此它是一个方便的标志。这也是我认为最好使用
setInterval
而不是setTimeout
的(少数)地方之一。setInterval
重复。所以:像这样使用:
尽管有上述所有内容,我还是想找到一种方法,通过检测某些完成条件已得到满足,使
setBgPosition
停止事情本身 。setTimeout
returns a timer handle, which you can use to stop the timeout withclearTimeout
.So for instance:
So you'd use that as:
Note that rather than having
setBgPosition
call itself again, I've just had it setc
back to0
. Otherwise, this wouldn't work. Also note that I've used0
as a handle value for when the timeout isn't pending;0
isn't a valid return value fromsetTimeout
so it makes a handy flag.This is also one of the (few) places I think you'd be better off with
setInterval
rather thansetTimeout
.setInterval
repeats. So:Used like this:
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.我知道这是一个老问题,无论如何我想发布我的方法。这样你就不必处理 TJ Crowder 解释的 0 技巧。
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.
处理超时循环的最简单方法
SIMPLIEST WAY TO HANDLE TIMEOUT LOOP
如果您想从函数内部停止循环,请尝试这样的操作:
您也可以将其包装在另一个函数中,只需确保您有一个计时器变量并使用clearInterval(theTimerVariable)来停止循环
Try something like this in case you want to stop the loop from inside the function:
You can also wrap this inside a another function, just make sure you have a timer variable and use clearInterval(theTimerVariable) to stop the loop
您需要使用一个变量来跟踪“完成度”,然后在循环的每次迭代中对其进行测试。如果done == true则返回。
You need to use a variable to track "doneness" and then test it on every iteration of the loop. If done == true then return.
由于这是用 extjs 标签标记的,因此可能值得查看 extjs 方法: http://docs.sencha.com/extjs/6.2.0/classic/Ext.Function.html#method-interval
这很像setInterval,但也负责范围,并允许传递参数:
当您想要停止时,可以使用
clearInterval
来停止它一个示例用例是:
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
This works much like setInterval, but also takes care of the scope, and allows arguments to be passed too:
when you want to stop you can use
clearInterval
to stop itAn example use case would be:
我不确定,但可能是你想要的:
I am not sure, but might be what you want:
在最上面的答案中,我认为
if (timer)
语句被错误地放置在stop()
函数调用中。它应该放在run()
函数调用中,例如if (timer)timer = setTimeout(run, 200)
。这可以防止将来的setTimeout
语句在调用stop()
后立即运行。编辑2: 对于同步函数调用来说,最重要的答案是正确的。如果您想进行异步函数调用,请使用我的。
下面给出的是我认为正确方法的示例(如果我错了,请纠正我,因为我还没有测试过这一点):
编辑 1: 这已经过测试并且按预期工作。
In the top answer, I think the
if (timer)
statement has been mistakenly placed within thestop()
function call. It should instead be placed within therun()
function call likeif (timer) timer = setTimeout(run, 200)
. This prevents futuresetTimeout
statements from being run right afterstop()
is called.EDIT 2: The top answer is CORRECT for synchronous function calls. If you want to make async function calls, then use mine instead.
Given below is an example with what I think is the correct way (feel to correct me if I am wrong since I haven't yet tested this):
EDIT 1: This has been tested and works as expected.
当任务完成并且您可以显示任务(在您的情况下是图像)时,在下次刷新时不要发送 javascript。如果您的服务器使用 PHP。
When the task is completed and you can display the task (image in your case), on the next refresh don't send the javascript. If your server is using PHP.