Почему этот код на основе setTimeout не работает в Firefox с небольшим таймаутом (работает в Internet Explorer / Chrome)?
У меня есть следующий код, который демонстрирует разницу в вызове долго выполняющейся функции непосредственно из триггера события, по сравнению с использованием.setTimeout()
Намеренное поведение:
Когда первая кнопка нажата, она появляется нажатой, вычисление выполняется в течение нескольких секунд, затем, когда вычисление заканчивается, кнопка снова отображается нажатой, и второй столбец изменяется с "пока не рассчитываю к "расчет сделан, (Я выиграл'• объяснить, почему это должно происходить;Это'объясняется в связанном ответе.)
Когда вторая кнопка нажата, кнопка нажимается немедленно; второй столбец сразу меняется на "вычисление ...» текст. Когда расчет заканчивается через несколько секунд, второй столбец меняется с "вычисление ...» к "расчет сделан ".
Что на самом деле происходит:
Это отлично работает в Chrome (обе кнопки ведут себя как положено)
Это прекрасно работает вInternet Explorer 8
Это НЕ работает в Firefox (v.25) как есть. В частности, вторая кнопка ведет себя на 100% как первая.
Изменение времени ожидания вsetTimeout()
от0
в1
не имеет никакого эффекта
Изменение времени ожидания вsetTimeout()
от0
в500
работает
Что оставляет меня с большой загадкой.
По всей причине, почемуsetTimeout()
работает, тогда как отсутствиет, задержка должна иметь нулевое влияние на то, как все работает,поскольку 'setTimeout()
Основная цель состоит в том, чтобы изменить порядок очередей здесь, а не задерживать события.
Итак, почему он не работает с задержкой 0 или 1 в Firefox, но работает как ожидается с задержкой 500 (и работает с любой задержкой в Интернетеисследователь8 / хром)?
ОБНОВЛЕНИЕ: в дополнение к исходному коду ниже, я также сделалJSFiddle, Но почему-то JSFiddle отказывается даже загружаться в мой интернетисследователь8, поэтому для этого тестирования требуется приведенный ниже код.
ОБНОВЛЕНИЕ 2: Кто-то поднял вопрос о возможной проблеме с настройкой конфигурацииdom.min_timeout_value
в Firefox. Я отредактировал его с 4 до 0, перезапустил браузер, и ничего не было исправлено. Он все еще терпит неудачу с таймаутом 0 или 1 и успешно с 500.
Вот мой исходный код - я просто сохранил его в HTML-файл на диске C: и открыл во всех трех браузерах:
Do long calc - bad status!
Not Calculating yet.
Do long calc - good status!
Not Calculating yet.
function long_running(status_div) {
var result = 0;
for (var i = 0; i < 1000; i++) {
for (var j = 0; j < 700; j++) {
for (var k = 0; k < 200; k++) {
result = result + i + j + k;
}
}
}
$(status_div).text('calclation done');
}
// Assign events to buttons
$('#do').on('click', function () {
$('#status').text('calculating....');
long_running('#status');
});
$('#do_ok').on('click', function () {
$('#status_ok').text('calculating....');
window.setTimeout(function (){ long_running('#status_ok') }, 0);
});
Для тестирования вам нужно изменить границы вложенного цикла на 300/100/100 для Интернетаисследователь8; или до 1000/1000/500 для Chrome, из-за разной чувствительностиэто JS занимает слишком много времени " ошибка в сочетании со скоростью двигателя JavaScript.