0
var count = 0;
for ( var i = 0; i < 4; i++ ) {
    setTimeout(
        function(){ 
            assert( i == count++, "Check the value of i." );
        },
        i * 200);
}

Объясните, пожалуйста, как работает этот код. Почему цикл бегает четыре раза со значением 4?

Deleted
  • 371
setback
  • 15
  • @setback, чёто я никогда не слышал о ф-ции assert в JS. Что она делает, поясните... – Rules Jan 16 '13 at 11:39
  • Я понимаю что сперва запускается цикл, бегает до значения четыре, потом запускается setTimeout. Но почему так? Может кто-то ссылку подкинет какую почитать..? – setback Jan 16 '13 at 11:41
  • @Rules возможно потому что это собственная функция?) – Palmervan Jan 16 '13 at 11:42
  • потому как i копируется по ссылке и через 200 мс цикл точно завершиться.
     assert( i == count++, "Check the value of i." );
    
    

    выполняется уже не в цикле.

    – KoVadim Jan 16 '13 at 11:42
  • @Rules имеется ввиду console.assert – ReinRaus Jan 16 '13 at 11:43
  • 1
    @Rules, функция тут не причем. Автор, вам нужно использовать замыкания. – lampa Jan 16 '13 at 11:44
  • @setback, Вы похоже неверно понимаете назначение setTimeout, это не sleep – ReinRaus Jan 16 '13 at 11:45
  • @Rules имеется ввиду console.assert

    А... Спасибо!, буду знать :)

    – Rules Jan 16 '13 at 11:46
  • Спасибо всем. Думаю что мне надо разобраться как работает setTimeout... a assert самописная функция,подсмотрел на stackoverflow - не знал тогда про console.assert - тот же самый принцип.. function assert(expression, description) { var message = expression ? 'PASS' : 'FAIL'; console.log(message + ': ' + description); } – setback Jan 16 '13 at 11:55
  • 1
    @lampa: замыкания ТС как раз и использует (по переменной i), разве нет? Ему нужно использовать их правильно. – VladD Jan 16 '13 at 12:05
  • @VladD правильно это и означает, что их нужно использовать :) Я же не вижу этого в скрипте. – lampa Jan 16 '13 at 13:53
  • 1
    @VladD всё правильно говорит, переменная i находится в замыкании по отношении к функции, которая передана в setTimeout – Spectre Jan 16 '13 at 13:57

2 Answers2

3

Проблема с обработчиками в цикле

Spectre
  • 12,309
  • Закрыть как повтор?

    +1.

    – VladD Jan 16 '13 at 12:24
  • спорный вопрос, с одной стороны тема вопроса аналогичная - цикл и асинхронные функции, с другой - это не так уж и очевидно – Spectre Jan 16 '13 at 12:34
3

демо

Сам setTimeOut работает асинхронно, то есть вне запускается 4 раза на выполнение функция assert i у Вас глобальная переменная и во время выполнения функции assert она уже равна 4 ем. Цикл пробегает быстрее.

явная демонстрация сего факта сначало цикл прошел потом сработали assert ы

Ильяс
  • 367
  • 1
  • 10