2014-01-11 2 views
0

Я очень опытен в Javascript, но я столкнулся с странной проблемой при разработке веб-приложения, где сценарий просто не ведет себя так, как должно быть. Как ни странно (необъяснимо, на самом деле), я не испытываю этой проблемы, когда использую свою автономную версию для разработки или после входа в систему. Однако, когда пользователь уже зарегистрировался и обновляет страницу, они сталкиваются с этой проблемой.Выполнение, связанное с уже установленными таймаутами

Вот пораженный метод (это буквально вся вещь):

_setLiveSyncTimeout: function (firstTestCall) { 
    if (firstTestCall) { 
     console.log('set next') 
     window.setTimeout(function() { 
      console.log(200, 'a'); 
      window.setTimeout(function() { 
       console.log(400, 'b'); 
      }, 200); 
     }, 200); 

     window.setTimeout(function() { 
      console.log(400, 'c'); 
     }, 400); 
    } 

    this._liveSyncTimeout = setTimeout(_(this.liveSyncNow).bind(this), this._liveSyncPeriod); 
} 

я заметил, что this.liveSyncNow не кажется, вызывался каждый раз, когда я бы ожидал, что это тоже, так что я добавил в вышеприведенный оператор if для отладки. Странно, когда вы пройдете в true, первый тайм-аут ('a') будет запущен, однако 'b' и 'c' не будут. Так как результат setTimeout не сохраняется в этих случаях, его буквально невозможно отменить, но, по всей видимости, они просто не запускаются. В том же случае, когда «b» и «c» не запускаются, тайм-аут для this.liveSyncNow также не запускается.

Из тестов выясняется, что при выполнении этой функции все тайм-ауты, ранее созданные в ней, будут отменены. Причина, по которой выполняется «a» тайм-аут, заключается в том, что между вызовом, где он создается, и следующим, существует разрыв в 200 мс.

Редактировать

Это происходит, по крайней мере, Chrome и Firefox.

Edit 2

Вот более простой пример вопроса. Это часть определения модели Backbone (вам не нужно об этом беспокоиться). Это буквально целая функция.

initialize: function() { 
    var a = setInterval(function() { 
     console.log('test') 
    }, 50); 
} 

SetInterval запускается три раза («тест» появляется в консоли три раза), а затем просто останавливается.

+0

Не удается воспроизвести, пожалуйста, добавьте полный пример, демонстрирующий эту проблему. –

+0

Может быть изменен метод 'setTimeout'. Я имею в виду что-то вроде этого 'window.setTimeout = function() {}' – Curious

+0

@ Zub Я так и думал. Я сделал 'console.log (setTimeout)', и он не изменился [собственный код]. –

ответ

0

Я испытываю эту проблему (неудивительно), поскольку совершенно несвязанная часть кода неправильно отменяет мои таймауты. Это произошло из-за того, что я использовал модифицированную версию setTimeout, которая вернула собственное инкрементно назначенное целое число, но я не использовал правильную модифицированную версию clearTimeout и вместо этого использовал оригинал window.clearTimeout. В результате мои хорошие таймеры были неправильно отменены.

Я нашел эту проблему и выследил изворотливый фрагмент кода, переписав clearTimeout и узнав, кто его назвал, когда и с каким идентификатором.

Я пытался не допустить этого в будущем путем присвоения идентификаторов в моем модом setTimeout убывающей, ниже 0.

Смежные вопросы