setTimeout выполняется после цикла for в JavaScript

1

Если мы запускаем setTimeout перед циклом for (который занимает 5-8 секунд) и запускаем его в консоли chrome dev, порядок выполнения должен быть

  1. Первый setTimeout
  2. Во- вторых for цикла
  3. Наконец console.log

    setTimeout(function(){
        console.log('setTimeout executes');
    },1000);
    for(var i=0;i<10000;i++){
        console.log('inside for loop');
    }
    console.log('after For Loop');
    

Но это не так, и порядок становится:

  1. Сначала for цикла
  2. Второй console.log
  3. и, наконец, setTimeout

Почему это происходит?

  • 1
    Второй порядок правильный
  • 1
    Как вы думаете, почему сообщение setTimeout executes должно появиться первым?
Показать ещё 4 комментария
Теги:

6 ответов

2
Лучший ответ

JS - синхронизация. Таким образом, весь код синхронизации выполняется первым, и все async идут в отдельном потоке, и они могут заканчиваться раньше, но им нужно подождать, пока не будет выполнен все код синхронизации.

setTimeout(function(){
    console.log('setTimeout executes');
},1000); // this function go async in separate thread
for(var i=0;i<10000;i++){ 
    console.log('inside for loop'); // sync
}
console.log('after For Loop'); // sync
// after all sync code async result will be called
// console.log('setTimeout executes'); will happen here

Если вы хотите получить полное представление о работе двигателей JS, прочитайте это. Это очень просто и помогает.

  • 0
    Неплохой ответ, но V8 - не единственный механизм JS, и код, передаваемый в setTimeout (в общем случае) не запускается в отдельном потоке, а в одном потоке выполнения, когда весь синхронный код завершен и (приблизительно) время задержки прошло.
  • 0
    Да, я попытался представить основную идею (потому что вопрос был от новичка). Вероятно, тема не лучшее слово, но не лучше сейчас.
0

setTimeout запускает код, который вы назвали анонимной функцией, по истечении таймера. В вашем случае он выполняет:

function(){
    console.log('setTimeout executes');
}

Это не останавливает нормальный поток javascript.

Чтобы получить поток, который вы хотите, вам нужно сделать это следующим образом:

setTimeout(function(){
    for(var i=0;i<10000;i++){
        console.log('inside for loop');
    }
    console.log('after For Loop');
},1000);

Чтобы понять это лучше, вы можете использовать этот инструмент визуализации: http://latentflip.com/loupe

  • 0
    setTimeout runs the code you mention as the anonymous function after the timer expires , WRONG, он не запускает переданный обратный вызов сразу же после того, как много секунд вы передали ему, пока очередь событий не пуста
  • 0
    ПРАВДА! Я согласен с тем, что вы говорите. Непрактично объяснять все ужасные детали асинхронности тому, кто все еще пытается сначала понять основы.
Показать ещё 3 комментария
0

Поскольку независимо от времени, прошедшего в setTimeout, даже если 0ms, это всегда занимает некоторое время, прежде чем оно выполняется, и поэтому любой другой достаточно небольшой фрагмент кода будет работать до вызова setTimeout.

0

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

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

0

setTimeout (function() {...}, 0) просто ставит в очередь код для запуска после завершения выполнения текущего стека вызовов. Это может быть полезно для некоторых вещей.

Так что да, это асинхронно, поскольку он прерывает синхронный поток, но на самом деле он не будет выполняться одновременно/в отдельном потоке. Если ваша цель - фоновая обработка, посмотрите на веб-мастеров. Также есть возможность использовать iframe для фоновой обработки.

0

вы пытаетесь обменять позицию

console.log('setTimeout executes');

а также

for(var i=0;i<10000;i++){
    console.log('inside for loop');
}
  • 0
    и вы можете гуглить разницу setInterval и setTimeout

Ещё вопросы

Сообщество Overcoder
Наверх
Меню