Проблема с использованием функции setTimeout - PullRequest
2 голосов
/ 06 октября 2011

Мне никогда не удавалось должным образом использовать функцию setTimeout, поэтому я попытался написать пример сценария для обновления индикатора выполнения, но, опять же, он не работает.Вместо этого вся программа запускается до того, как индикатор выполнения обновляется до 100%.Может ли кто-нибудь взглянуть на этот код и сказать, что я делаю неправильно?

Код, который я пытаюсь использовать, взят из http://digitalbush.com/projects/progress-bar-plugin/

Спасибо!

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script language="javascript" type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script src="http://digitalbush.com/wp-content/uploads/2007/02/jqueryprogressbar.js" type="text/javascript"></script>
<title>Progress Bar test</title>
</head>
<body>
<style>
    /* progress bar container */
    #progressbar{
        border:1px solid black;
        width:200px;
        height:20px;
        position:relative;
        color:black; 
    }
    /* color bar */
    #progressbar div.progress{
        position:absolute;
        width:0;
        height:100%;
        overflow:hidden;
        background-color:#369;
    }
    /* text on bar */
    #progressbar div.progress .text{
        position:absolute;
        text-align:center;
        color:white;
    }
    /* text off bar */
    #progressbar div.text{
        position:absolute;
        width:100%;
        height:100%;
        text-align:center;
    }
</style>

<div id="progressbar"></div>
<input type='button' value='start' onClick='run()' />

<script>
function run() {
    for (i=0; i<100; i++) {
        setTimeout( function() {
            $("#progressbar").reportprogress(i);
        }, 500);
    }
}
</script>
</body>
</html>

Ответы [ 2 ]

3 голосов
/ 06 октября 2011

setTimeout не равно sleep (JavaScript не имеет sleep).

Когда вы зацикливаетесь, вы устанавливаете функцию на запуск через 500 мс, а затем немедленно установите его снова на 500 мс и т. Д.Таким образом, вы устанавливаете его для запуска 100 раз за 500 мс, и устанавливаете i равным 100 до первого запуска (так как для запуска цикла 100 раз требуется JS-движок менее чем за полсекунды).

Вы хотите что-то похожее на это:

var interval, i = 0;
interval = setInterval(function () {
    if (i === 100) {
        clearInterval(interval);
    } else {
        $("#progressbar").reportprogress(i);
        i++;
    }
}, 500);
2 голосов
/ 06 октября 2011

Проблема в том, что переменная i становится частью замыкания и, когда функция выполняется, уже равна 100.

Код, который вы в настоящее время в буквальном смысле создает сотню тайм-аутовссылаясь на ту же переменную (глобальный я).К тому времени, когда все функции будут выполнены, я равняюсь 100, поэтому вы сообщаете 100 как текущий прогресс 100 раз.

Правильная версия должна выглядеть следующим образом:

function run() {
    var i = 0;
    setTimeout( function updateProgress() {
        $("#progressbar").reportprogress(i++);
        if (i < 100){
            setTimeout(updateProgress, 500);
        }
    }, 500);
}

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

...