Если мы запускаем setTimeout
перед циклом for
(который занимает 5-8 секунд) и запускаем его в консоли chrome dev, порядок выполнения должен быть
setTimeout
for
цикла Наконец 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');
Но это не так, и порядок становится:
for
циклаconsole.log
setTimeout
Почему это происходит?
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, прочитайте это. Это очень просто и помогает.
setTimeout
(в общем случае) не запускается в отдельном потоке, а в одном потоке выполнения, когда весь синхронный код завершен и (приблизительно) время задержки прошло.
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
setTimeout runs the code you mention as the anonymous function after the timer expires
, WRONG, он не запускает переданный обратный вызов сразу же после того, как много секунд вы передали ему, пока очередь событий не пуста
Поскольку независимо от времени, прошедшего в setTimeout
, даже если 0ms, это всегда занимает некоторое время, прежде чем оно выполняется, и поэтому любой другой достаточно небольшой фрагмент кода будет работать до вызова setTimeout.
Если вы хотите узнать, почему, setTimeout
является асинхронным. Javascript только гарантирует, что этот обратный вызов не будет называться до времени, указанного вами, но не гарантирует, что это произойдет именно после этого. Он помещает вызов в очередь событий (я думаю), и если что-то еще там, этот обратный вызов должен будет ждать.
Вы можете узнать намного больше в книгах "Вы не знаете JS", которые вы можете найти здесь, прочитать асинхронные части.
setTimeout (function() {...}, 0) просто ставит в очередь код для запуска после завершения выполнения текущего стека вызовов. Это может быть полезно для некоторых вещей.
Так что да, это асинхронно, поскольку он прерывает синхронный поток, но на самом деле он не будет выполняться одновременно/в отдельном потоке. Если ваша цель - фоновая обработка, посмотрите на веб-мастеров. Также есть возможность использовать iframe для фоновой обработки.
вы пытаетесь обменять позицию
console.log('setTimeout executes');
а также
for(var i=0;i<10000;i++){
console.log('inside for loop');
}
setTimeout executes
должно появиться первым?