Автор: Сухджиндер Арора Переводчик: Front-end Xiaozhi Источник: среда
Ставь лайк и смотри, поиск в WeChat【Переезд в мир】Обратите внимание на этого человека, который не имеет большого фабричного прошлого, но имеет восходящий и позитивный настрой. эта статья
GitHub
GitHub.com/QQ449245884…Он был включен, статьи были классифицированы, и многие мои документы и учебные материалы были систематизированы.
Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.
JS
является однопоточным языком программирования, что означает, что одновременно может обрабатываться только одна вещь, т.JSМеханизм может обрабатывать только один оператор в одном потоке за раз.
Хотя однопоточность упрощает программирование кода, потому что тогда нам не нужно слишком беспокоиться о проблемах параллелизма, это также означает выполнение длительных операций, таких как сетевые запросы, при блокировании основного потока.
Представьте, что вы запрашиваете какие-то данные у API: в зависимости от ситуации серверу требуется некоторое время для обработки запроса, блокируя основной поток, в результате чего веб-страница долгое время не отвечает. Вот почему был введен асинхронный JS. Используйте асинхронность (например, функции обратного вызова,promise
,async/await
), который может длительное время выполнять сетевые запросы, не блокируя основной поток.
Прежде чем мы поймем, как работает асинхронность, давайте посмотрим, как работает синхронизация.
Как работает синхронный JS?
Углубленное изучение асинхронностиJS
Перед этим разберемся с синхронизациейJS
код находится вJavaScript
исполнение в двигателе. Например:
const second = () => {
console.log('Hello there!');
}
const first = () => {
console.log('Hi there!');
second();
console.log('The End');
}
first();
Чтобы понять, как приведенный выше код работает вJS
В двигателе надо понимать что такоеконтекст выполненияа такжестек вызовов(также известный как стек выполнения).
Код функции выполняется в контексте выполнения функции, а глобальный код выполняется в глобальном контексте выполнения. Каждая функция имеет свой собственный контекст выполнения.
стек вызовов
Как следует из названия, стек вызовов имеетLIFO
Стек структур (последний вошел, первый вышел), используемый для хранения всех контекстов выполнения, созданных во время выполнения кода.
JS
Существует только один стек вызовов, потому что это однопоточный язык программирования. Стек вызовов имеетLIFO
структура, что означает, что элементы могут быть добавлены или удалены только из вершины стека.
Возвращаясь к приведенному выше коду, попытайтесь понять, как кодJS
выполняется в двигателе.
const second = () => {
console.log('Hello there!');
}
const first = () => {
console.log('Hi there!');
second();
console.log('The End');
}
first();
Что тут происходит?
Когда этот код выполняется, глобальный контекст выполнения (представленный main() ) создается и помещается на вершину стека вызовов. при встречеfirst()
, он помещается на вершину стека.
Следующий,console.log('Hi there!')
помещается на вершину стека, а когда это делается, он извлекается из стека. После этого звонимsecond()
,следовательноsecond()
Функции помещаются на вершину стека.
console.log('Hello there!')
помещается на вершину стека и извлекается из стека по завершении.second()
Функция завершается, поэтому она выталкивается из стека.
console.log(“the End”)
помещается на вершину стека и удаляется по завершении. Позже,first()
Функция завершается, поэтому удалите ее из стека.
В этот момент программа завершает свое выполнение, поэтому глобальный контекст выполнения (main()) извлекается из стека.
Как работает асинхронный JS?
Теперь, когда мы сделали стек вызовов и синхронизациюJAS
С базовым пониманием того, как это работает, вернемся к асинхронности.JS
начальство.
Что блокирует?
Предположим, мы выполняем обработку изображений или сетевые запросы синхронно. Например:
const processImage = (image) => {
/**
* doing some operations on image
**/
console.log('Image processed');
}
const networkRequest = (url) => {
/**
* requesting network resource
**/
return someData;
}
const greeting = () => {
console.log('Hello World');
}
processImage(logo.jpg);
networkRequest('www.somerandomurl.com');
greeting();
Требуется время для обработки изображений и сетевых запросов, когдаprocessImage()
Когда функция вызывается, это занимает некоторое время в зависимости от размера изображения.
processImage()
Когда функция завершится, она будет удалена из стека. тогда позвониnetworkRequest()
функцию и поместите ее в стек. Кроме того, для завершения выполнения требуется некоторое время.
Наконец, когдаnetworkRequest()
Когда функция завершится, вызовитеgreeting()
функция.
Поэтому нам приходится ждать таких функций, какprocessImage()
илиnetworkRequest()
Заканчивать. Это означает, что эти функции блокируют стек вызовов или основной поток. Таким образом, выполняя приведенный выше код, мы не можем делать ничего другого, что не идеально.
Каково решение?
Самое простое решение — это асинхронные обратные вызовы, которые вы, ребята, используете, чтобы сделать ваш код неблокирующим. Например:
const networkRequest = () => {
setTimeout(() => {
console.log('Async Code');
}, 2000);
};
console.log('Hello World');
networkRequest();
используется здесьsetTimeout
метод имитации сетевого запроса. пожалуйста, помнитеsetTimeout
нетJS
часть двигателя, этоWeb Apiчасть.
Чтобы понять, как выполняется этот код, мы должны понимать больше таких понятий, как опрос событий и очереди обратного вызова (или очереди сообщений).
Опрос событий, веб-API и очередь сообщений неJavaScript
Часть движка, но браузерJavaScript
Среда выполнения или часть среды выполнения Nodejs JavaScript (для Nodejs). В Nodejs веб-api заменен на c/c++ api.
Теперь вернемся к приведенному выше коду и посмотрим, как он выполняется асинхронно.
const networkRequest = () => {
setTimeout(() => {
console.log('Async Code');
}, 2000);
};
console.log('Hello World');
networkRequest();
console.log('The End');
Когда приведенный выше код загружается в браузере,console.log(' Hello World ')
помещается в стек и извлекается из стека по завершении. Далее вы столкнетесьnetworkRequest()
вызов, тем самым подтолкнув его к вершине стека.
СледующийsetTimeout()
Функция вызывается, поэтому она помещается на вершину стека.setTimeout()
Есть два параметра:
-
- обратный вызов и
-
- Время в миллисекундах (мс).
setTimeout()
Метод запускает 2-секундный таймер в среде веб-API. В настоящее время,setTimeout()
Завершено и извлечено из стека.cosole.log(“the end”)
помещается в стек, выполняется после завершения и удаляется из стека.
Тем временем таймер истек, и теперь обратный вызов помещается в очередь сообщений. Но обратный вызов не выполняется сразу, здесь начинается опрос событий.
опрос событий
Задача опроса событий состоит в том, чтобы прослушивать стек вызовов и определять, пуст ли стек вызовов. Если стек вызовов пуст, он проверит очередь сообщений, чтобы увидеть, есть ли какие-либо ожидающие выполнения обратные вызовы.
В этом случае очередь сообщений содержит обратный вызов, а стек вызовов в этот момент пуст. Таким образом, опрос событий помещает обратные вызовы на вершину стека.
Послеconsole.log(“Async Code”)
помещается на вершину стека, выполняется и извлекается из стека. В этот момент обратный вызов завершен, поэтому он удаляется из стека, и программа наконец завершается.
Очередь сообщений также содержит обратные вызовы от событий DOM, таких как события щелчка и события клавиатуры. Например:
document.querySelector('.btn').addEventListener('click',(event) => {
console.log('Button Clicked');
});
Для событий DOM прослушиватель событий находится в среде веб-API, ожидая некоторого события (в данном случае события щелчка), когда событие происходит, функция обратного вызова помещается в очередь сообщений, ожидающих выполнения.
Аналогично, опрос событий проверяет, пуст ли стек вызовов, и помещает обратные вызовы событий в стек, когда стек вызовов пуст, и выполняет обратный вызов.
Задержка выполнения функции
мы также можем использоватьsetTimeout
чтобы отложить выполнение функции до тех пор, пока стек не будет опустошен. Например
const bar = () => {
console.log('bar');
}
const baz = () => {
console.log('baz');
}
const foo = () => {
console.log('foo');
setTimeout(bar, 0);
baz();
}
foo();
распечатать результат:
foo
baz
bar
Когда этот код запускается, первая функцияfoo()
Вызыватьfoo
Внутренне мы называемconsole.log('foo')
,ПотомsetTimeout()
называется,bar()
в качестве функции обратного вызова и когда0
секундный таймер.
Теперь, если бы мы не использовалиsetTimeout
, bar()
Функция выполнится немедленно, но используйтеsetTimeout
а также0
секундный таймер, будетbar
Выполнение откладывается до тех пор, пока стек не станет пустым.
0
секунд спустя,bar()
Обратный вызов помещается в очередь сообщений, ожидающих выполнения, но он будет выполнен только тогда, когда стек полностью опустеет, то есть вbaz
а такжеfoo
после завершения функции.
очередь задач ES6
Мы видели, как выполняются асинхронные обратные вызовы и события DOM, они используют очередь сообщений для хранения ожидания выполнения всех обратных вызовов.
ES6 представил концепцию очереди задач, очередь задачJS
серединаpromise
Использовал. Разница между очередью сообщений и очередью задач заключается в том, что приоритет очереди задач выше, чем у очереди сообщений, а это означает, чтоpromise
Задание будет выполнено перед обратным вызовом в очереди сообщений, например:
const bar = () => {
console.log('bar');
};
const baz = () => {
console.log('baz');
};
const foo = () => {
console.log('foo');
setTimeout(bar, 0);
new Promise((resolve, reject) => {
resolve('Promise resolved');
}).then(res => console.log(res))
.catch(err => console.log(err));
baz();
};
foo();
распечатать результат:
foo
baz
Promised resolved
bar
мы можем видетьpromise
существуетsetTimeout
выполнен раньше, потому чтоpromise
Ответы хранятся в очередях задач, которые имеют более высокий приоритет, чем очереди сообщений.
резюме
Итак, мы узнали об асинхронностиJS
как это работает, и такие понятия, как стеки вызовов, циклы событий, очереди сообщений и очереди задач, которые вместе составляютJS
Среда выполнения.虽然成为一名出色的JS
Разработчикам не нужно изучать все эти концепции, но знать их полезно.
Ошибки, которые могут существовать после развертывания кода, не могут быть известны в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку журнала.Кстати, я рекомендую всем полезный инструмент мониторинга ошибок.Fundebug.
оригинал:blog.bit SRC.IO/понять я…
общаться с
Статья постоянно обновляется каждую неделю. Вы можете выполнить поиск «Big Move to the World» в WeChat, чтобы прочитать и обновить ее как можно скорее (на одну или две статьи раньше, чем в блоге). Эта статья находится на GitHub.GitHub.com/QQ449245884…Он был включен, и многие мои документы были разобраны. Добро пожаловать в Звезду и совершенство. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Кроме того, обратите внимание на паблик-аккаунт и ответьте в фоновом режиме.Благосостояние, вы можете увидеть преимущества, вы знаете.