Почему этот код на основе 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.

Ответы на вопрос(3)

Ваш ответ на вопрос