1

Я делаю расширение chrome для личного использования, которое будет рекурсивно вызывать setTimeout. Я хотел бы убедиться, что ни при каких обстоятельствах это расширение не создает несколько цепей setTimeouts.Как я могу обеспечить только одну цепочку рекурсивных setTimeouts?

Я сделал это так, что, когда я нажимаю действие браузера, он вызывает clearTimeout. Тем не менее, я беспокоюсь о том, когда я перезагружу расширение, может быть, старая цепочка тайм-аутов продолжается? И могут быть другие сценарии, о которых я не думаю. Есть ли проверенный и надежный метод предотвращения случайного создания нескольких цепей тайм-аутов?

Похоже, что нет никакого способа перечислить активные JavaScript таймеров: Viewing all the timouts/intervals in javascript?

+0

Можете добавить код? Потому что не совсем ясно, как именно вы «рекурсивно называете» setTimeout. В любом случае, если вы сделаете это в фоновом сценарии страницы, тогда все таймеры будут уничтожены при перезагрузке. Вызывается только сценарий с инъецированным контентом, если вы не перезагружаете веб-страницы. Кроме того, я бы рекомендовал использовать API 'chrome.alarms'. – wOxxOm

ответ

1

Я решаемые подобный случай, как это раньше:

var timer; 
function foo(){ 
    if(!timer) 
    timer = setTimeout(function(){ 
     //should print once every second only 
     console.log(new Date()); 
     timer = null; 
     foo(); 
    }, 1000) 
} 

foo(); 
foo(); 

Так как JavaScript работает синхронный код для завершения перед обработкой следующее событие безопасно.

1

Мой импульс был бы использовать clearTimeout для подавления конкурирующих тайм-аута, но мне нравится ответ Йохана гов, а также, в особенности, когда обобщаются:

var setOneTimeout = (function() { 
    var timer 
    return function(f, timeout) { 
    if (!timer) { 
     timer = setTimeout(function() { 
     timer = null 
     f() 
     }, timeout) 
    } 
    } 
})() 

setOneTimeout(function() { console.log('foo') }, 500) 
setOneTimeout(function() { console.log('bar') }, 500) 
/* outputs "foo", only. */ 

Или, если вы будете иметь несколько категорий тайм-аутов и только требуется один «рабочий» тайм-аут в каждой категории:

var setNamedTimeout = (function() { 
    var timer = {} 
    return function(name, f, timeout) { 
    if (!timer[name]) { 
     timer[name] = setTimeout(function() { 
     timer[name] = null 
     f() 
     }, timeout) 
    } 
    } 
})() 

setNamedTimeout('foo', function() { console.log('foo') }, 500) 
setNamedTimeout('bar', function() { console.log('bar') }, 500) 
setNamedTimeout('bar', function() { console.log('bar') }, 500) 
setNamedTimeout('bar', function() { console.log('bar') }, 500) 
setNamedTimeout('bar', function() { console.log('bar') }, 500) 
setNamedTimeout('foo', function() { console.log('foo') }, 500) 
/* outputs only one instance of "foo" and "bar" */ 
Смежные вопросы