Писать статьи о SETTIMEOUT на прошлой неделе, на самом деле, это также задействовало операционный механизм JS. Итак, на этой неделе поговорим о механизме запуска JavaScript.
Тогда сначала задайте вопрос 😁.
Почему JavaScript однопоточный?
Позвольте мне ответить:
Однопоточность означает, что одновременно может выполняться только одно действие. Разве это не неэффективно? Нет, на самом деле однопоточная особенность javascript связана с его назначением. В качестве языка сценариев браузера JavaScript в основном используется для взаимодействия с пользователем и управления DOM. Если это не один поток, когда один поток добавляет содержимое в узел DOM, другой поток удаляет содержимое этого узла DOM, это нормально, разве это не беспорядок. Таким образом, javascript может быть только однопоточным.
Хотя javascript является однопоточным, в javascript есть концепция синхронизации и асинхронности, которая решает проблему блокировки js.
Синхронные и асинхронные:
1. Синхронизация:
Если функция возвращает значение, вызывающая сторона может получить ожидаемый результат (то есть получить ожидаемое возвращаемое значение или увидеть ожидаемый эффект), то функция является синхронной.
Объясните кодом:
console.log('Hello');
Если вы видите ожидаемый эффект при возврате функции: Hello выводится на консоль
2. Асинхронный:
Если вызывающая сторона не может получить ожидаемый результат при возврате функции, но должна получить его определенными средствами в будущем, то функция является асинхронной.
Объяснение кода:
fs.readFile('test.txt', 'utf8', function(err, data) {
console.log(data);
});
В приведенном выше коде мы хотим прочитать содержимое файла foo.txt с помощью функции fs.readFile и распечатать его. Но когда функция fs.readFile вернется, ожидаемого нами результата не произойдет, а будет ждать, пока файл будет полностью прочитан. Это может занять много времени, если файл большой.
Небольшое резюме:
-
Как только вызов синхронного метода начинается, вызывающая сторона должна дождаться возврата вызова метода, прежде чем продолжить последующее поведение.
-
Вызов асинхронного метода больше похож на передачу сообщения: после запуска вызов метода немедленно возвращается, и вызывающая сторона может продолжать последующие операции. Однако асинхронные методы обычно выполняются "реально" в другом потоке. Весь процесс не будет мешать работе звонящего.
javascript может выполнять синхронные задачи и асинхронные задачи. Поставив операции чтения файлов и ajax-запросов в очередь задач, я все равно могу пошагово продолжить выполнение следующих задач. Итак, javascript все еще может быть очень 6. Итак, асинхронная задача — это только задача на выполнение асинхронной операции, и что в ней будет происходить?
Очередь задач:
Как упоминалось выше, в javascript есть два типа задач: синхронные задачи и асинхронные задачи.
Синхронная задача относится к задаче, поставленной в очередь на выполнение в основном потоке, и последняя задача может быть выполнена только после завершения выполнения первой задачи.
Асинхронные задачи относятся к тому, что они не входят в основной поток и входят в задачу «очереди задач», только «Запрос задачи» уведомляет основной поток, и некоторые асинхронные задачи могут быть выполнены, задача войдет в основной поток.
Давайте посмотрим на маленький каштан:
console.log("a");
setTimeout(function () {
console.log("b");
},0);
console.log("c");
//a
//c
//b
Код в js выполняется сверху вниз.При выполнении первой строки кода консоль выводит a.При выполнении второй строки кода встречается функция setTimeout.Поскольку функция setTimeout является асинхронной функцией, браузер запомнит это событие, добавит его в расписание, а затем поместит функцию обратного вызова этого события в очередь задач. В это время программа основного потока продолжает выполняться до пятой строки: console.log("c"), выполнить это, и консоль выводит c. В это время основной поток пуст, и он отправится в очередь задач, чтобы узнать, есть ли какие-то задачи, которые можно выполнить.
Чтобы лучше проиллюстрировать очередь задач и цикл событий, давайте посмотрим на схему. 😄
Эта картинка уже нарисовала поток событийного цикла js. обработать:- Все задачи синхронизации выполняются в основном потоке, образуя стек выполнения.
- Когда стек выполнения в основном потоке пуст, проверяем, пуста ли очередь событий, если пуста, продолжаем проверку, если не пуста, выполняем 3;
- Извлеките голову очереди задач и поместите ее в стек выполнения;
- выполнять задания;
- Проверить стек выполнения, если стек выполнения пуст, вернуться к шагу 2, если нет, продолжить проверку;
Цикл событий:
Цикл событий на самом деле является циклом, который выталкивает и извлекает стек. В приведенном выше примере упоминается setTimeout, а как насчет setInterval, Promise и т.д. и т.п., там много асинхронных функций. Но эти асинхронные задачи делятся на макрозадачи и микрозадачи:
Макрозадачи включают в себя: скрипт setTimeout, setInterval, setImmediate, ввод-вывод, рендеринг пользовательского интерфейса.
Микрозадача включает в себя: process.nextTick, Promises, Object.observe, MutationObserver.
Каждый раз, когда петли события пожары:
- Выполнение задач в основном потоке выполнения — это выполнение первой задачи макрозадачи, такой как задача сценария.
- Выньте выполнение задачи в микрозадаче, пока она не будет очищена.
- Вынести выполнение задачи в макро-задачу.
- Выньте выполнение задачи в микрозадаче, пока она не будет очищена.
- Повторите 3 и 4.
По сути, then и catch промисов — это микрозадачи, а не их собственный внутренний код.
Уведомление:
-
Реализация в браузере браузера и узла отличается.
-
Очередь задач "первым пришел, первым вышел".
Затем подойдите к маленькому каштану, чтобы проверить, полностью ли вы его поняли:
console.log('global')
for (var i = 1;i <= 5;i ++) {
setTimeout(function() {
console.log(i)
},i*1000)
console.log(i)
}
new Promise(function (resolve) {
console.log('promise1')
resolve()
}).then(function () {
console.log('then1')
})
setTimeout(function () {
console.log('timeout2')
new Promise(function (resolve) {
console.log('timeout2_promise')
resolve()
}).then(function () {
console.log('timeout2_then')
})
}, 1000)
Вывод консоли:
Этот блог может быть очень полезен для углубления понимания:Глубокое понимание цикла событий JavaScript (1) - цикл событийСуммировать:
В основном это касается цикла событий js на стороне браузера. Эта статья может помочь лучше понять различные циклы обработки событий в средах узлов и браузеров:Различные циклы событий браузера и узла (Event Loop)