Асинхронный код Flashcards
Что такое синхронный код ? Какой вид поточности используется при выполнении кода в JS ?
Выполнение JS-кода — однопоточное. Это значит, что в конкретный момент времени движок может выполнять не более одной строки кода. То есть вторая строка не будет выполнена, пока не выполнится первая.
Такое выполнение кода (строка за строкой) называется синхронным.
Как работает стек вызовов ?
За что ответственен цикл событий ?
Цикл событий отвечает за выполнение кода, сбор и обработку событий и выполнение подзадач из очереди.
Опишите работу Стека, Web API, Очереди задач в простой программе с SetTimeout
С помощью чего осуществляется работа с асинхронным кодом ?
колбэк — это первый способ обработать какое-либо асинхронное действие.
Изначально колбэки были единственным способом работать с асинхронным кодом в JavaScript. Большая часть асинхронного API Node.js была написана именно на колбэках и создана для использования с колбэками.
Что такое ад коллбэков ? Каким средством это было решено ?
Ряд асинхронных задач, которые зависят друг от друга: то есть первая задача запускает по завершении вторую, вторая — третью и т. д.
Что такое промисы ?
Промис (Promise) — специальный объект JavaScript, который используется для написания и обработки асинхронного кода.
Асинхронные функции возвращают объект Promise в качестве значения. Внутри промиса работает асинхронная операция, которая управляет его состоянием.
Промис может находиться в одном из трёх состояний:
pending — стартовое состояние, операция стартовала;
fulfilled — получен результат;
rejected — ошибка.
Поменять состояние можно только один раз: перейти из pending либо в fulfilled, либо в rejected:
У промиса есть методы then() и catch(), которые позволяют выполнять код при изменении его состояния.
Какие существует недостатки промисов ?
Однако промисы — это тоже не серебряная пуля. У них есть несколько недостатков:
Код не такой лаконичный, как мог быть.
В цепочке промисов, как на примере (со стрелочными функциями), невозможно выставить брейкпоинт, потому что нет тела функции. Приходится раскрывать функцию.
Стек ошибок может содержать в себе then.then.then.then….
Вложенные условия сильно увеличивают количество кода и ухудшают читаемость.
Для решения этих проблем придумали асинхронные функции.
Как пишется промис ?
const promise = new Promise(function (resolve, reject) {
// делаем асинхронную операцию
const data = resolve(data) // запрос в БД, API, etc. // переводим промис в состояние fulfilled и отдаём наружу результат операции
})
const errorPromise = new Promise(function (resolve, reject) {
reject(new Error(‘ошибка’)) // переводим промис в состояние rejected и отдаём наружу ошибку
})
Какую аналогию из реальной жизни можно привести для описания работы создающего, потребляющего кода и промиса ?
Это аналогия из реальной жизни для ситуаций, с которыми мы часто сталкиваемся в программировании:
Есть «создающий» код, который делает что-то, что занимает время. Например, загружает данные по сети. В нашей аналогии это – «певец».
Есть «потребляющий» код, который хочет получить результат «создающего» кода, когда он будет готов. Он может быть необходим более чем одной функции. Это – «фанаты».
Promise (по англ. promise, будем называть такой объект «промис») – это специальный объект в JavaScript, который связывает «создающий» и «потребляющий» коды вместе. В терминах нашей аналогии – это «список для подписки». «Создающий» код может выполняться сколько потребуется, чтобы получить результат, а промис делает результат доступным для кода, который подписан на него, когда результат готов.
let promise = new Promise(function(resolve, reject) {
// функция-исполнитель (executor)
// “певец”
});
Чем является resolve,reject ?
Её аргументы resolve и reject – это колбэки, которые предоставляет сам JavaScript.
Какие внутренние свойства есть у промисов ?
У объекта promise, возвращаемого конструктором new Promise, есть внутренние свойства:
state («состояние») — вначале “pending” («ожидание»), потом меняется на “fulfilled” («выполнено успешно») при вызове resolve или на “rejected” («выполнено с ошибкой») при вызове reject.
result («результат») — вначале undefined, далее изменяется на value при вызове resolve(value) или на error при вызове reject(error).
let promise = new Promise(function(resolve, reject) {
// функция-исполнитель (executor)
// “певец”
});
После выполнения функции исполнителя что он вызывает ?
он должен вызвать один из этих колбэков:
resolve(value) — если работа завершилась успешно, с результатом value.
reject(error) — если произошла ошибка, error – объект ошибки.
Сколько раз может быть изменено состояние промиса ?
Один раз. Все последующие вызовы resolve и reject будут проигнорированы
Идея в том, что задача, выполняемая исполнителем, может иметь только один итог: результат или ошибку.
Также заметим, что функция resolve/reject ожидает только один аргумент (или ни одного). Все дополнительные аргументы будут проигнорированы.