Как остановить цикл 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);
}
поэтому out out выглядит так:
http://jsfiddle.net/TTkre/
Мне пришлось использовать setBgPosition(); внутри, чтобы это выполнялось в цикле, поэтому теперь моя проблема заключается в том, как остановить этот цикл, как только я хочу [загрузить закончен]?
Ответы
Ответ 1
setTimeout
возвращает дескриптор таймера, который вы можете использовать для остановки таймаута с помощью clearTimeout
.
Итак, например:
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;
}
}
Итак, вы использовали бы это как:
var stop = setBgPosition();
// ...later, when you're ready to stop...
stop();
Обратите внимание, что вместо того, чтобы setBgPosition
снова вызвать себя, я только что установил c
обратно на 0
. В противном случае это не сработает. Также обратите внимание, что я использовал 0
как значение дескриптора, когда тайм-аут не ожидает; 0
не является допустимым возвращаемым значением из setTimeout
, поэтому он делает удобный флаг.
Это также одно из (нескольких) мест, которые, как мне кажется, вам лучше с 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);
}
Используется следующим образом:
var timer = setBgPosition();
// ...later, when you're ready to stop...
clearInterval(timer);
Несмотря на все вышеизложенное, я хотел бы найти способ сделать setBgPosition
остановить вещи самостоятельно, обнаружив, что выполнено какое-то условие завершения.
Ответ 2
Я знаю, что это старый вопрос, я бы хотел опубликовать мой подход. Таким образом, вам не нужно обрабатывать трюк 0, который использовал Т. Дж. Кроудер.
var keepGoing = true;
function myLoop() {
// ... Do something ...
if(keepGoing) {
setTimeout(myLoop, 1000);
}
}
function startLoop() {
keepGoing = true;
myLoop();
}
function stopLoop() {
keepGoing = false;
}
Ответ 3
Вам нужно использовать переменную для отслеживания "doneness", а затем проверить ее на каждой итерации цикла. Если выполнено == 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
Ответ 4
СИМПЛИСТИЧЕСКИЙ ПУТЬ К РЕГУЛИРОВАНИЮ ВРЕМЕНИ ЗАГРУЗКИ
function myFunc (terminator = false) {
if(terminator) {
clearTimeout(timeOutVar);
} else {
// do something
timeOutVar = setTimeout(function(){myFunc();}, 1000);
}
}
myFunc(true); // -> start loop
myFunc(false); // -> end loop
Ответ 5
Поскольку это помечено тегом extjs, возможно, стоит посмотреть на метод extjs: http://docs.sencha.com/extjs/6.2.0/classic/Ext.Function.html#method-interval
Это работает так же, как 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();
когда вы хотите остановить, вы можете использовать clearInterval
, чтобы остановить его
clearInterval(bgPositionTimer);
Пример использования:
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);
}
});
Ответ 6
Я не уверен, но может быть, что вы хотите:
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();