Я буду использовать следующий пример для объяснения:
setTimeout(() => {
console.log('1 ms timeout');
}, 1); // Moved to async queue at time = T0
setTimeout(() => {
console.log('0 ms timeout')
}, 0); // Moved to async queue after 1 ms that synchronous call to setTimeout takes i.e. at T1
// So at T1, queue will be [("1ms timeout", 0), ("0ms timeout", 0)]
Следовательно, будет напечатано
1 ms timeout
0 ms timeout
Понимание приведенного выше: Вызов setTimeouts является синхронным (даже если его обратный вызов помещен в asyn c queue), т.е. мы вызываем setTimeout () и переходим к следующему оператору - само это синхронное действие может занять 1 мс.
Другими словами, 1 мс - это слишком мало времени, поэтому к моменту времени JS движок увидит второй асинхронный c оператор, первый из них уже потратил 1 мс в очереди.
Я также предлагаю вам попробовать следующее
setTimeout(() => {
console.log("First");
}, 2); // queue at T0 = [("First", 2)]
const forLoopLimit = 100;
for (var i = 0; i < forLoopLimit; i++){
console.log(i * 10000);
} // Assume that it takes about 3 milliseconds
// queue at T3 = [("First", 0)]
setTimeout(() => {
console.log("Second");
}, 0); // Assume it takes 0 milliseconds.
// queue at T4 = [("First", 0), ("Second", 0)]
Это напечатает First
до Second
, даже если у первого был тайм-аут 2 мс по сравнению с последним, имеющим 0 мс. Теперь измените forLoopLimit
на 1 или даже 10, вы увидите, что синхронная задача теперь не занимает 3 миллисекунды, а Second
печатается перед First
Также стоит попробовать:
console.log(Date.now());
console.log(Date.now());
Попробуйте несколько раз выше, и вы увидите, что иногда журналы консоли имеют разные временные метки. Грубо говоря, console.log()
и Date.now()
занимают 0,5 мс. Это не что иное, как время для вызова / выполнения синхронного материала.