Оптимизация производительности — механизм цикла событий js (цикл событий)

Архитектура JavaScript Promise

предисловие

Когда я раньше работал над внешним интерфейсом, я мог больше сосредоточиться на вещах бизнес-уровня, таких как ряд относительно неглубоких технических уровней, таких как вырезание диаграмм, реализация взаимодействий и вызовы интерфейсов. конечной технологии, недостаточно просто освоить эти знания. Да, вы должны научиться понимать, как отображать страницу с URL-адреса, а затем вы можете видеть то, что хотите видеть, и управлять этим. Понимание некоторых механизмов рендеринга на нижняя часть браузера отличная Внешний интерфейс имеет важное значение.Эта статья о том, как выполняется один поток js.Если есть какие-либо недостатки, пожалуйста, укажите, и я внесу исправления вовремя.


Цикл событий — это много мест, задействованных в нашей повседневной работе, но все могут не знать об этом, это метод рендеринга, вызванный механизмом цикла событий, поднимающий 🌰:
console.log(1)
setTimeout(()=>{
    console.log(3)
},1)
console.log(2)

Очевидно, что результат: 1, 2, 3

Независимо от того, где setTimeout находится в текущей области, результатом будет 1, 2, 3. Да ведь это механизм цикла событий цикла событий.

Все знают, что js является однопоточным, и если вы мало знаете о многопроцессорности и многопоточности, вы можете обратиться к этим двум статьям:

Многопроцессорная архитектура браузера

Многопоточность процесса рендеринга в браузере

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

Приведенный выше пример на самом деле связан с проблемой, то есть время, установленное моим setTimeout, равно 1 мс.Обратите внимание:

W3c предусматривает в стандарте HTML, что время setTimeout менее 4 мс считается за 4 мс.

Еще одна вещь, которую следует отметить, это то, что иногда, когда некоторые великие боги используют js для выполнения некоторых операций с анимацией, им нравится использовать setTimeout вместо setInterval, потому что setTimeout помещает текущий метод в очередь задач по истечении этого времени, а setInterval принудительно добавьте текущий метод в очередь задач, что может очень плохо сказаться на работе пользователя с текущей страницей, и эффект может застрять, поэтому обратите внимание:

setTimeout - это отложенное выполнение, но не выполняется сразу после задержки.

На самом деле цикл событий в основном делится на три части: основной поток, очередь макросов (макротаска), микроочередь (микрозадача)

Очередь задач js делится на синхронные задачи и асинхронные задачи, все синхронные задачи выполняются в основном потоке, а асинхронные задачи могут быть в макрозадаче или микрозадаче.

основной поток

Основной поток — это простое понимание, то есть содержимое, содержащееся в теге script, к которому осуществляется доступ, или при прямом доступе к файлу js содержимое в нем может быть в текущей области видимости.прямое исполнениеВесь контент (исполняемые методы, новые объекты и т. д.) выполняется в основном потоке, а те, что добавляются в очередь задач, не учитываются. Все то же самое, например:

//index.html
<html>
    <head></head>
    <body>
        <script src="index.js"></script>
        <script>
            console.log(1)
            setTimeout(() => {
               console.log(3) 
            },1)
        </script>
    </body>
</html>

//index.js
console.log(2)
setTimeout(() => {
   console.log(4) 
},1)

В результате 1 и 2 выполняются в основном потоке, а 3 и 4 выбрасываются в очередь задач.

Очередь макросов (макросаска)

setTimeout, setInterval, setImmediate, ввод-вывод, рендеринг пользовательского интерфейса

Микроочередь (микрозадача)

Обещание. Затем, Process.nextTick, объект. Сохранение (устаревшее)


код сначала
console.log(1)
process.nextTick(() => {
  console.log(8)
  setTimeout(() => {
    console.log(9)
  })
})
setTimeout(() => {
  console.log(2)
  new Promise(() => {
    console.log(11)
  })
})
requestIdleCallback(() => {
  console.log(7)
})
let promise = new Promise((resolve,reject) => {
  setTimeout(() => {
    console.log(10)
  })
  resolve()
  console.log(4)
})
fn()
console.log(3)
promise.then(() => {
  console.log(12)
})
function fn(){
  console.log(6)
}

Результат 1, 4, 6, 3, 12, 8, 2, 11, 10, 9, 7

Этот метод написания может охватывать более 80% сценариев механизма цикла событийного цикла.Начнем разбираться с конкретным механизмом работы.

js выполняется сверху вниз, поэтому первым печатается1, продолжайте идти вниз;

Встреча с Process.NextTick, поскольку он принадлежит microSK, а код текущего основного потока еще не выполнен, поэтому показано, что он брошен в очередь micros, временно не печатая;

В это время я встречал SetTimeout, а setTimeout представлял собой очередь макросов (Macrotask);

requestIdleCallback, который не выполняется немедленно и не принадлежит ни к какой очереди, и здесь подробно объясняться не будет;

При инстанцировании промиса setTimeout здесь продолжает кидать в очередь макросов (макротаск) и выполняется успешный метод При вызове promise.then он сработает, но здесь не будет напечатан , а затем найти С помощью консоли печатать прямо здесь4;

Функция fn вызывается напрямую и печатается напрямую6;

консоль, печать напрямую3;

promise.then, потому что он принадлежит микроочереди, но он вызывается при создании экземпляра обещания, поэтому он будет выполнен в начале микроочереди;

На данный момент в основном потоке ничего не может быть выполнено, запустим микро-очередь (микрозадачу):

Поскольку promise.then вызывается заранее, он выполнится первым, выводя12;

В микроочереди (микрозадаче) есть еще одна, это вышеприведенный process.nextTick, выполните ее и напечатайте8, на этот раз я обнаружил, что у него есть setTimeout и поставил его в очередь макросов (макросаска);

На этом микро-очередь заканчивается, и начинается макро-очередь (макротаска):

Самый внешний setTimeout помещается в начале, поэтому сначала выполните его, напечатайте2, обнаружил, что в нем был создан экземпляр промиса, выполненный напрямую и напечатанный11;

Следующее, что нужно сделать, это setTimeout в обещании, напечатать10;

Остался последний setTimeout, который находится в процессе.nextTick, напечатайте9;

Здесь основной поток, макрозадача, микрозадача, выполняется, когда все выполняется, будет выполняться RequestIdlecallback, печать7;

requesIdleCallback будет выполняться последовательно в течение периода простоя текущего браузера.В течение всего процесса вы можете добавить несколько requestIdleCallbacks, но они не будут выполняться, а будут выполняться только в период простоя в соответствии с порядком вызовов.

console.log(1)
process.nextTick(() => {
  console.log(8)
  setTimeout(() => {
    console.log(9)
    requestIdleCallback(() => {
      console.log(13)
    })
  })
})
setTimeout(() => {
  console.log(2)
  new Promise(() => {
    console.log(11)
  })
})
requestIdleCallback(() => {
  console.log(7)
})
let promise = new Promise((resolve,reject) => {
  setTimeout(() => {
    console.log(10)
  })
  resolve()
  console.log(4)
  requestIdleCallback(() => {
    console.log(14)
  })
})
fn()
console.log(3)
promise.then(() => {
  console.log(12)
  requestIdleCallback(() => {
    console.log(15)
  })
})
function fn(){
  console.log(6)
  requestIdleCallback(() => {
    console.log(16)
  })
}

Результат: 1, 4, 6, 3, 12, 8, 2, 11, 10, 9, 7, 14, 16, 15, 13.

Поскольку эта часть не связана с циклом событий, а относится к исключительному методу, здесь будет дано только краткое объяснение, а углубленное исследование проводиться не будет.

Суммировать

На самом деле цикл событий объясняется простыми словами, то есть:

1. Сначала выполнить основной поток

2. Найдите очередь макросов (макрозадачу) и поместите ее в очередь макросов (макрозадачу).

3. При встрече с микроочередью (микрозадачей) поместить ее в микроочередь (микрозадачу)

4. Выполняется основной поток

5. Выполнить микроочередь (микрозадачу), выполнение микроочереди (микрозадачи) завершено

6. Выполнить задачу в очереди макросов (макрозадачу) один раз и завершить выполнение

7. Выполнить микроочередь (микрозадачу) и завершить выполнение

8, цикл по очереди. . .

Этот процесс на самом деле является механизмом цикла событий js (цикл событий), о котором мы хотим поговорить конкретно.


заключительные замечания

Это сводная статья, написанная мной, читая объяснения некоторых великих богов в Интернете и мое собственное понимание механизма цикла событий js (цикл событий).Если в нем что-то не так, пожалуйста, укажите, я внесу коррективы, как только насколько это возможно. Если вы считаете, что это нормально, чтобы поблагодарить вас, пожалуйста, поставьте лайк.