Базовое сообщение загрузки Javascript во время завершения обработки js - PullRequest
4 голосов
/ 31 марта 2011

Я уверен, что об этом уже 1000 раз спрашивали, в основном все, что я хочу сделать, - это изменить содержимое элемента страницы для отображения сообщения о загрузке, пока мой другой код JavaScript (довольно ресурсоемкий) завершается. Проблема в том, что сообщение не отображается до тех пор, пока не будет завершена «другая обработка JS», что полностью разрушает его назначение. упрощенный пример ...

<html>
<head>
    <title> crappity crapness </title>
    <script type="text/javascript">
        function showMessage(){
            document.getElementById("content").innerHTML = "please wait while we waste some time";
        }

        function wasteTime(){
            //alert("oh joy");
            pausecomp(3000);
            //alert("marvelous!");
        }

        function pausecomp(millis) 
        {
            var date = new Date();
            var curDate = null;

            do { curDate = new Date(); } 
            while(curDate-date < millis);
        } 

    </script>
</head>
<body>
    <div id="content">Blah</div>
    <br/>
    <a href="http://www.google.com" onclick="showMessage(); wasteTime();"> link </a>
</body>

если я раскомментирую предупреждение "oh Joy", текст в div будет немедленно обновлен. как мне заставить это работать без предупреждения?

Я знаю, что мне не хватает чего-то простого. Спасибо

Ответы [ 3 ]

6 голосов
/ 31 марта 2011

Похоже, вы сталкиваетесь с тем фактом, что Javascript является однопоточным, а браузеры - нет.

По сути, вы не можете запускать несколько кусков Javascript одновременно.Тем не менее, браузер все еще должен делать что-то вне выполнения Javascript и продолжает делать это, когда может.Проблема заключается в том, является ли изменение DOM синхронным (т. Е. Выполнение JS прекращается до тех пор, пока оно не выполнено) или асинхронным (выполнение JS продолжается) не определено.Большинство браузеров делают последнее.Но выполнение JS по-прежнему имеет довольно высокий приоритет, и многие обновления DOM откладываются до тех пор, пока выполнение JS не должно остановиться и ждать.Окно предупреждения является отличным примером, поскольку оно ожидает ввода данных пользователем.

Способ сделать то, что вы хотите сделать, - воспользоваться преимуществом setTimeout(), которое позволяет текущему фрагменту JS завершить, затем браузер можетзавершите обновление DOM, и затем он сможет выполнить JS, ожидая запуска по таймауту.

2 голосов
/ 31 марта 2011

Было бы неплохо, если бы вы могли вызывать функцию showMessage асинхронно.В других языках вы можете сделать это с потоками, а в HTML5 вы можете сделать это с рабочими, которые предназначены именно для такого рода вещей, но сейчас вы можете просто использовать setTimeout, что делает код впервый аргумент выполняется через определенное время, позволяя текущему коду выполнить его раньше.

Изменить

   onclick="showMessage(); wasteTime();"

на

   onclick="showMessage; setTimeout(wasteTime,5);"> 
1 голос
/ 31 марта 2011

Ваш pausecomp(3000) по существу блокирует перерисовку браузера из-за цикла while. Я бы сделал что-то вроде этого:

function wasteTime(){
    setTimeout(runNext, 3000);
}

function runNext(){
     alert("marvelous!");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...