Подробно объясните EventLoop, который часто задают на продвинутых фронтенд-интервью.

Node.js внешний интерфейс JavaScript опрос
Подробно объясните EventLoop, который часто задают на продвинутых фронтенд-интервью.

Прежде всего, что такое EventLoop?

Весь рабочий механизм js также называется Event Loop (цикл событий)

EventLoop разделен на два типа: боковая сторона браузера и сторона узла

Почувствуй код

 setTimeout(() => {
        console.log(1)
        Promise.resolve(3).then(data => console.log(data))
      }, 0)
      
setTimeout(() => {
        console.log(2)
      }, 0)
//浏览器 1 3 2
//node 1 2 3

Браузерный цикл событий

Во-первых, будет стек во время выполнения, а затем будет очередь событий и пространство микрозадач (названное вами)

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

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

Есть картинки и правда (это некрасиво! Не говори некрасиво)

Микрозадачи и макрозадачи

  • Тогда обещание микрозадачи (MutationObserver)
  • Задачи макросов setInterval, setTimeout, setImmediate(ie), MessageChannel

EventLoop на стороне узла

Придумайте уродливую картинку

Очередное текстовое описание, попробуйте сами запутаться

  • Порядок выполнения setTimeout и setImmediate не фиксирован и зависит от времени подготовки узла

Дизайн setImmediate выполняется, когда фаза опроса завершена, то есть фаза проверки; setTimeout предназначен для выполнения, когда фаза опроса простаивает и по истечении установленного времени; но порядок, в котором он выполняется в фазе таймера, зависит от контекста текущего цикла событий, если они вызываются вне асинхронного i Обратный вызов /o (в Поскольку следующим этапом является этап проверки), последовательность выполнения вызова в вводе-выводе неопределенна, и перед выполнением цикла необходимо увидеть трудоемкую ситуацию.

  • Каждое поле на приведенном выше рисунке соответствует очереди событий.Когда цикл событий выполняется до определенного этапа, в свою очередь будет выполняться очередь, соответствующая текущему этапу. Когда очередь будет выполнена или количество исполнений превысит строку, она перейдет к следующему этапу.
  • Микрозадача — переключить столбец — выполнить

Не говорите глупостей, давайте кодировать

setImmediate(() => {
  console.log('setImmediate1')  
  setTimeout(() => {
    console.log('setTimeout1')
  }, 0);
})
setTimeout(()=>{
  console.log('setTimeout2')
  setImmediate(()=>{
    console.log('setImmediate2')
  })
},0);
//首先setImmediate和setTimeout执行顺序不固定 
//所以setImmediate1和setTimeout2,打印顺序不定
//假设 setImmediate1先打印   有两种顺序
//1.执行顺序是 setImmediate1  setTimeout2  setTimeout1 setImmediate2
//2.执行顺序是 setImmediate1  setTimeout2  setImmediate2 setTimeout1
// 1.setImmediate1打印后把setTimeout1放进timer队列 然后执行setTimeout2 这时候把setImmediate2放进check队列中  打印setTimeout2 发现timer中还有setTimeout1 他就会把timer对列中的执行完 才会执行下一队列的代码
//然后打印setTimeout1, 切换对列到check  打印setImmediate2
//2. setImmediate1打印后把setTimeout1放进timer队列 然后执行setTimeout2 这时候把setImmediate2放进check队列中  打印setTimeout2 这个时候node执行过快setTimeout1还没有到时间,所以切换对列执行setImmediate2 然后是setTimeout1
//setTimeout第二个参数虽然是0,但是都有默认时间一般是4ms左右

еще один вопрос

setImmediate(() => {
  console.log('setImmediate1')  
  setTimeout(() => {
    console.log('setTimeout1')
  }, 0);
})
setTimeout(()=>{
  console.log('setTimeout2')
  process.nextTick(()=>console.log('nextTick'))
  setImmediate(()=>{
    console.log('setImmediate2')
  })
},0);
//假设setImmediate1先
//setImmediate1  setTimeout2 setTimeout1  nextTick setImmediate2
//setImmediate1  setTimeout2 nextTick setImmediate2 setTimeout1
//微任务会在切换对列时执行  上面从timer对列切换到check对列时nextTick执行
//上面一题明白了这一个也明白了

еще один вопрос

let fs = require('fs');
fs.readFile('./1.txt',function () {
  console.log(1);
  setTimeout(() => {
    console.log('setTimeout')
  }, 0);
  setImmediate(() => {
    console.log('setImmediate')
  });
});

//顺序固定 1 setImmediate setTimeout
// 为什么呢?看上面的图  首先readFile肯定是poll对列   执行时把setTimeout setImmediate放到各自队列 然后按上下顺序查找对列  查找到check队列发现有 就把setImmediate打印出  然后顺序检查下一队列close没有 循环 再次从上往下找  直到timer打印setTimeout

Вышеприведенный контент — это mac vscode, который я пробовал.

Есть два типа микрозадач, nextTick и then. Так какая из этих двух задач быстрее?

 Promise.resolve('123').then(res=>{
   console.log(res);
   
 })
  process.nextTick(() => console.log('nextTick'))
  
  //顺序  nextTick 123
  //很明显  nextTick快