Занят индикатор состояния гонки в Javascript - PullRequest
2 голосов
/ 21 мая 2009

У меня есть следующий код (javascript / jquery) для отображения индикатора занятости (после задержки) во время загрузки изображения:

function imgUpdate(arg) {
    var loaded = false;

    $("#image").one("load", function(){
        loaded = true;
        $("#busyIndicator").hide();
    });

    setTimeout(function(){
        if (!loaded) {
            $("#busyIndicator").show();
        }
    }, 250);

    $("#image")[0].src = arg;
}

Иногда индикатор поднимается и остается включенным. Как это возможно, если движок JavaScript браузера является однопоточным? (Кстати, в Firefox 3).

Одно примечание: это происходит, когда загружаемое изображение уже кэшировано.

Еще одно замечание: если я войду в свою консоль firebug, все строки в imgUpdate будут выполнены, но сообщение журнала внутри обработчика onload никогда не печатается при последующих вызовах imgUpdate.

Ответы [ 4 ]

1 голос
/ 21 мая 2009

Очистка тега src изображения, похоже, решает проблему:

function imgUpdate(arg) {
    var loaded = false;

    $("#image").one("load", function(){
        loaded = true;
        $("#busyIndicator").hide();
    });

    setTimeout(function(){
        if (!loaded) {
            $("#busyIndicator").show();
        }
    }, 250);

    $("#image")[0].src = "";
    $("#image")[0].src = arg;
}
1 голос
/ 21 мая 2009

Есть ли какой-нибудь другой javascript на странице, который ломается? Если это так, то это может быть не условие гонки - JS может просто прекратить выполнение, прежде чем busyIndicator снова будет скрыт ...

1 голос
/ 21 мая 2009

Мне сложно воспроизвести это.

Вот реализация того, что вы делаете:

Версия с использованием кэширования: http://jsbin.com/uwuho

Версия с предотвращением кэширования: (использует параметр, чтобы избежать кэширования) http://jsbin.com/oguvi

Нажмите F5 / Ctrl-F5, чтобы увидеть, как это происходит. (в частности, в версии, которая предотвращает кеширование)

С кэшированием или без него ни одна из версий не выполняет то, что вы описали.

Ваша проблема , вероятно, лежит в другом месте.

0 голосов
/ 21 мая 2009

Возможно, вы захотите очистить тайм-аут в вашем обратном вызове, чтобы он не срабатывал при загрузке изображения.

var timer = null;
function imgUpdate(arg) {
    var loaded = false;
    timer = setTimeout(function(){ 
        $("#busyIndicator").show();
        timer = null;
    }, 250);        
    $("#image").one("load", function(){
        if (timer) {
            clearTimeout(timer);
            timer = null;
        }
        $("#busyIndicator").hide();
    });
    $("#image")[0].src = arg;
}
...