Long Polling (длинные опросы)
Длинные опросы – это самый простой способ поддерживать постоянное соединение с сервером, не используя при этом никаких специфических протоколов (типа WebSocket или Server Sent Events).
Его очень легко реализовать, и он хорошо подходит для многих задач.
Как это происходит:
- Запрос отправляется на сервер;
- Сервер не закрывает соединение, пока у него не возникнет сообщение для отсылки;
- Когда появляется сообщение – сервер отвечает на запрос, посылая его;
- Браузер немедленно делает новый запрос.
P.S. на картинке примерный код клиентской функции
#LongPolling #сетевые_запросы
Длинные опросы – это самый простой способ поддерживать постоянное соединение с сервером, не используя при этом никаких специфических протоколов (типа WebSocket или Server Sent Events).
Его очень легко реализовать, и он хорошо подходит для многих задач.
Как это происходит:
- Запрос отправляется на сервер;
- Сервер не закрывает соединение, пока у него не возникнет сообщение для отсылки;
- Когда появляется сообщение – сервер отвечает на запрос, посылая его;
- Браузер немедленно делает новый запрос.
P.S. на картинке примерный код клиентской функции
subscribe,
которая реализует длинные опросы.#LongPolling #сетевые_запросы
👍4🔥1
XMLHttpRequest
Несмотря на наличие слова «XML» в названии, XMLHttpRequest может работать с любыми данными, а не только с XML. Мы можем загружать/скачивать файлы, отслеживать прогресс и многое другое.
Алгоритм работы:
1) Создать
2) Инициализировать его;
3) Послать запрос;
4) Слушать события на
P.S. На сегодняшний день не обязательно использовать
#xhr #сетевые_запросы
XMLHttpRequest
– это встроенный в браузер объект, который даёт возможность делать HTTP-запросы к серверу без перезагрузки страницы.Несмотря на наличие слова «XML» в названии, XMLHttpRequest может работать с любыми данными, а не только с XML. Мы можем загружать/скачивать файлы, отслеживать прогресс и многое другое.
Алгоритм работы:
1) Создать
XMLHttpRequest;
2) Инициализировать его;
3) Послать запрос;
4) Слушать события на
xhr
, чтобы получить ответ.P.S. На сегодняшний день не обязательно использовать
XMLHttpRequest
, так как существует другой, более современный метод fetch.#xhr #сетевые_запросы
👍6🔥2
Опциональная цепочка '?.'
Опциональная цепочка
Опциональная цепочка
P.S. Эта возможность была добавлена в язык недавно. В старых браузерах может понадобиться полифил.
#опциональная_цепочка #основы
Опциональная цепочка
?.
— это безопасный способ доступа к свойствам вложенных объектов, даже если какое-либо из промежуточных свойств не существует.Опциональная цепочка
?.
останавливает вычисление и возвращает undefined
, если часть перед ?.
имеет значение undefined
или null
.P.S. Эта возможность была добавлена в язык недавно. В старых браузерах может понадобиться полифил.
#опциональная_цепочка #основы
👍5🔥3
Копирование объектов
Одним из фундаментальных отличий объектов от примитивных типов данных является то, что они хранятся и копируются «по ссылке».
Примитивные типы: строки, числа, логические значения – присваиваются и копируются «по значению».
Переменная хранит не сам объект, а его «адрес в памяти», другими словами «ссылку» на него.
Чтобы реально скопировать объект, нам нужно создать новый объект и повторить структуру дублируемого объекта, перебирая его свойства и копируя их.
#object #основы
Одним из фундаментальных отличий объектов от примитивных типов данных является то, что они хранятся и копируются «по ссылке».
Примитивные типы: строки, числа, логические значения – присваиваются и копируются «по значению».
Переменная хранит не сам объект, а его «адрес в памяти», другими словами «ссылку» на него.
Чтобы реально скопировать объект, нам нужно создать новый объект и повторить структуру дублируемого объекта, перебирая его свойства и копируя их.
#object #основы
👍7🔥4
Наследование классов
Наследование
Ключевое слово
#наследование #классы
Наследование
extends
пришло в JS с ES6 синтаксисом.Ключевое слово
extends
работает, используя прототипы. Оно устанавливает Rabbit.prototype.[[Prototype]]
в Animal.prototype
. Так что если метод не найден в Rabbit.prototype
, JavaScript берёт его из Animal.prototype
.#наследование #классы
👍8🔥2
Решайте практические тесты из собеседований на нашем втором канале @tests_js
🔥2👍1
Динамические импорты
Инструкции экспорта и импорта, которые мы рассматривали в предыдущем посте, называются «статическими». Синтаксис у них весьма простой и строгий.
Во-первых, мы не можем динамически задавать никакие из параметров
Путь к модулю должен быть строковым примитивом и не может быть вызовом функции. Вот так работать не будет:
Во-вторых, мы не можем делать импорт в зависимости от условий или в процессе выполнения.
Все эти проблемы решает выражение
Выражение import()
Выражение
Использовать его мы можем динамически в любом месте кода, как показано на скрине выше.
#динамический_импорт #модули
Инструкции экспорта и импорта, которые мы рассматривали в предыдущем посте, называются «статическими». Синтаксис у них весьма простой и строгий.
Во-первых, мы не можем динамически задавать никакие из параметров
import
.Путь к модулю должен быть строковым примитивом и не может быть вызовом функции. Вот так работать не будет:
Во-вторых, мы не можем делать импорт в зависимости от условий или в процессе выполнения.
Все эти проблемы решает выражение
import(module)
.Выражение import()
Выражение
import(module)
загружает модуль и возвращает промис, результатом которого становится объект модуля, содержащий все его экспорты.Использовать его мы можем динамически в любом месте кода, как показано на скрине выше.
#динамический_импорт #модули
👍4🔥3
Eval: выполнение строки кода
Встроенная функция
Синтаксис:
Строка кода может быть большой, содержать переводы строк, объявления функций, переменные и т.п.
Результатом
Использование
В современной разработке на JavaScript
Причина такого отношения достаточно проста: давным-давно JavaScript был не очень развитым языком, и многие вещи можно было сделать только с помощью
Встроенная функция
eval
позволяет выполнять строку кода.Синтаксис:
let result = eval(code);
Строка кода может быть большой, содержать переводы строк, объявления функций, переменные и т.п.
Результатом
eval
будет результат выполнения последней инструкции.Использование
В современной разработке на JavaScript
eval
используется весьма редко. Есть даже известное выражение – «eval is evil» («eval – это зло»).Причина такого отношения достаточно проста: давным-давно JavaScript был не очень развитым языком, и многие вещи можно было сделать только с помощью
eval
. Но та эпоха закончилась более десяти лет назад.👍14🔥7
Промисификация
Промисификация – это длинное слово для простого преобразования. Мы берём функцию, которая принимает колбэк и меняем её, чтобы она вместо этого возвращала промис.
Такие преобразования часто необходимы в реальной жизни, так как многие функции и библиотеки основаны на колбэках, а использование промисов более удобно, поэтому есть смысл «промисифицировать» их.
Например, у нас есть
Давайте промисифицируем её. Новая функция
#promise #продвинутый
Промисификация – это длинное слово для простого преобразования. Мы берём функцию, которая принимает колбэк и меняем её, чтобы она вместо этого возвращала промис.
Такие преобразования часто необходимы в реальной жизни, так как многие функции и библиотеки основаны на колбэках, а использование промисов более удобно, поэтому есть смысл «промисифицировать» их.
Например, у нас есть
loadScript(src, callback)
(см. левую часть картинки)Давайте промисифицируем её. Новая функция
loadScriptPromise(src)
будет делать то же самое, но будет принимать только src
(не callback
) и возвращать промис (см. правую часть картинки)#promise #продвинутый
👍17❤4🔥4
Callbacks (Колбэки)
Колбэк функция - это такая функция, которая вызывается после выполнения какой-то асинхронности.
В данном примере описана функция динамической подгрузки скриптов с колбеком, после загрузки. Функция
Колбэки используются повсеместно, не только в JavaScript.
#callback #колбэк #продвинутый
Колбэк функция - это такая функция, которая вызывается после выполнения какой-то асинхронности.
В данном примере описана функция динамической подгрузки скриптов с колбеком, после загрузки. Функция
callback
выполнится, когда скрипт будет полностью загружен на странице.Колбэки используются повсеместно, не только в JavaScript.
#callback #колбэк #продвинутый
👍30❤2
Микрозадачи
Асинхронные задачи требуют правильного управления. Для этого стандарт предусматривает внутреннюю очередь
Как сказано в спецификации:
- Очередь определяется как первым-пришёл-первым-ушёл (FIFO): задачи, попавшие в очередь первыми, выполняются тоже первыми.
- Выполнение задачи происходит только в том случае, если ничего больше не запущено.
Или, проще говоря, когда промис выполнен, его обработчики
Вот почему сообщение «код выполнен» в примере выше будет показано первым.
#микрозадачи #промисы
Асинхронные задачи требуют правильного управления. Для этого стандарт предусматривает внутреннюю очередь
PromiseJobs
, более известную как «очередь микрозадач (microtask queue)» (термин V8).Как сказано в спецификации:
- Очередь определяется как первым-пришёл-первым-ушёл (FIFO): задачи, попавшие в очередь первыми, выполняются тоже первыми.
- Выполнение задачи происходит только в том случае, если ничего больше не запущено.
Или, проще говоря, когда промис выполнен, его обработчики
.then/catch/finally
попадают в очередь. Они пока не выполняются. Движок JavaScript берёт задачу из очереди и выполняет её, когда он освободится от выполнения текущего кода.Вот почему сообщение «код выполнен» в примере выше будет показано первым.
#микрозадачи #промисы
👍20❤4
Цепочка промисов
Идея состоит в том, что результат первого промиса передаётся по цепочке обработчиков
Поток выполнения такой:
- Начальный промис успешно выполняется через 1 секунду
- Затем вызывается обработчик в
- Возвращаемое им значение передаётся дальше в следующий обработчик
- …и так далее.
В итоге результат передаётся по цепочке обработчиков, и мы видим несколько alert подряд, которые выводят:
#промисы #цепочка_промисов
Идея состоит в том, что результат первого промиса передаётся по цепочке обработчиков
.then
.Поток выполнения такой:
- Начальный промис успешно выполняется через 1 секунду
(*)
,- Затем вызывается обработчик в
.then
(**)
.- Возвращаемое им значение передаётся дальше в следующий обработчик
.then
(***)
- …и так далее.
В итоге результат передаётся по цепочке обработчиков, и мы видим несколько alert подряд, которые выводят:
1
→ 2
→ 4
.#промисы #цепочка_промисов
👍11🔥3
Асинхронные итераторы
Асинхронные итераторы похожи на обычные итераторы, но имеют некоторые синтаксические отличия.
Чтобы сделать объект итерируемым асинхронно:
1. Используется
2.
3. Чтобы перебрать такой объект, используется цикл
На картинке выше вы можете увидеть итерируемый объект
#генераторы #асинхронные_итераторы
Асинхронные итераторы похожи на обычные итераторы, но имеют некоторые синтаксические отличия.
Чтобы сделать объект итерируемым асинхронно:
1. Используется
Symbol.asyncIterator
вместо Symbol.iterator
2.
next()
должен возвращать промис.3. Чтобы перебрать такой объект, используется цикл
for await (let item of iterable)
.На картинке выше вы можете увидеть итерируемый объект
range
.#генераторы #асинхронные_итераторы
👍12🔥2
Proxy
Объект
Прокси используются во многих библиотеках и некоторых браузерных фреймворках.
Синтаксис:
-
-
При операциях над
#разное #proxy
Объект
Proxy
«оборачивается» вокруг другого объекта и может перехватывать (и, при желании, самостоятельно обрабатывать) разные действия с ним, например чтение/запись свойств и другие. Далее мы будем называть такие объекты «прокси».Прокси используются во многих библиотеках и некоторых браузерных фреймворках.
Синтаксис:
let proxy = new Proxy(target, handler);
-
target
– это объект, для которого нужно сделать прокси, может быть чем угодно, включая функции.-
handler
– конфигурация прокси: объект с «ловушками» («traps»): методами, которые перехватывают разные операции, например, ловушка get
– для чтения свойства из target
, ловушка set
– для записи свойства в target
и так далее.При операциях над
proxy
, если в handler
имеется соответствующая «ловушка», то она срабатывает, и прокси имеет возможность по-своему обработать её, иначе операция будет совершена над оригинальным объектом target
.#разное #proxy
👍14🔥5
Proxy: ловушки
Чтобы активировать другие его возможности, добавим ловушки.
Для большинства действий с объектами в спецификации JavaScript есть так называемый «внутренний метод», который на самом низком уровне описывает, как его выполнять. Например,
Ловушки как раз перехватывают вызовы этих внутренних методов. Полный список методов, которые можно перехватывать, перечислен в спецификации Proxy, а также в таблице ниже.
Для каждого внутреннего метода в этой таблице указана ловушка, то есть имя метода, который мы можем добавить в параметр
P.S. На картинке отображена таблица со всеми доступными ловушками.
#разное #proxy #ловушки
Proxy
– это особый объект, у него нет собственных свойств. С пустым handler
он просто перенаправляет все операции на target
.Чтобы активировать другие его возможности, добавим ловушки.
Для большинства действий с объектами в спецификации JavaScript есть так называемый «внутренний метод», который на самом низком уровне описывает, как его выполнять. Например,
[[Get]]
– внутренний метод для чтения свойства, [[Set]]
– для записи свойства, и так далее. Эти методы используются только в спецификации, мы не можем обратиться напрямую к ним по имени.Ловушки как раз перехватывают вызовы этих внутренних методов. Полный список методов, которые можно перехватывать, перечислен в спецификации Proxy, а также в таблице ниже.
Для каждого внутреннего метода в этой таблице указана ловушка, то есть имя метода, который мы можем добавить в параметр
handler
при создании new Proxy
, чтобы перехватывать данную операцию.P.S. На картинке отображена таблица со всеми доступными ловушками.
#разное #proxy #ловушки
👍7🔥4
Proxy: Значение по умолчанию с ловушкой «get»
Чаще всего используются ловушки на чтение/запись свойств.
Чтобы перехватить операцию чтения,
Он срабатывает при попытке прочитать свойство объекта, с аргументами:
-
-
-
Давайте применим ловушку
Например, сделаем числовой массив, так чтобы при чтении из него несуществующего элемента возвращался
#разное #proxy #ловушки
Чаще всего используются ловушки на чтение/запись свойств.
Чтобы перехватить операцию чтения,
handler
должен иметь метод get(target, property, receiver)
.Он срабатывает при попытке прочитать свойство объекта, с аргументами:
-
target
– это оригинальный объект, который передавался первым аргументом в конструктор new Proxy
,-
property
– имя свойства,-
receiver
– если свойство объекта является геттером, то receiver
– это объект, который будет использован как this
при его вызове. Обычно это сам объект прокси (или наследующий от него объект). Прямо сейчас нам не понадобится этот аргумент, подробнее разберём его позже.Давайте применим ловушку
get
, чтобы реализовать «значения по умолчанию» для свойств объекта.Например, сделаем числовой массив, так чтобы при чтении из него несуществующего элемента возвращался
0
.#разное #proxy #ловушки
🔥11👍4
Proxy: Валидация с ловушкой «set»
Допустим, мы хотим сделать массив исключительно для чисел. Если в него добавляется значение иного типа, то это должно приводить к ошибке.
Ловушка
-
-
-
-
-
Ловушка
#разное #proxy #ловушки
Допустим, мы хотим сделать массив исключительно для чисел. Если в него добавляется значение иного типа, то это должно приводить к ошибке.
Ловушка
set
срабатывает, когда происходит запись свойства.-
set(target, property, value, receiver)
:-
target
– это оригинальный объект, который передавался первым аргументом в конструктор new Proxy
,-
property
– имя свойства,-
value
– значение свойства,-
receiver
– аналогично ловушке get
, этот аргумент имеет значение, только если свойство – сеттер.Ловушка
set
должна вернуть true
, если запись прошла успешно, и false
в противном случае (будет сгенерирована ошибка TypeError
).#разное #proxy #ловушки
🔥6👍3❤1
Продвинутая реализация каррирования
Выше представлен "продвинутый" вариант функции каррирования.
Когда мы запускаем её, есть две ветви выполнения
1. Вызвать сейчас: если количество переданных аргументов
2. Частичное применение: в противном случае
На картинке выше показано, что произойдёт в случае
#разное #каррирование
Выше представлен "продвинутый" вариант функции каррирования.
Когда мы запускаем её, есть две ветви выполнения
if
:1. Вызвать сейчас: если количество переданных аргументов
args
совпадает с количеством аргументов при объявлении функции (func.length
) или больше, тогда вызов просто переходит к ней.2. Частичное применение: в противном случае
func
не вызывается сразу. Вместо этого, возвращается другая обёртка pass
, которая снова применит curried
, передав предыдущие аргументы вместе с новыми. Затем при новом вызове мы опять получим либо новое частичное применение (если аргументов недостаточно) либо, наконец, результат.На картинке выше показано, что произойдёт в случае
sum(a, b, c)
. У неё три аргумента, так что sum.length = 3
.#разное #каррирование
🔥15👍4
Строки, Intl.Collator
Intl.Collator - конструктор для «сортировщиков», которые представляют собой объекты, позволяющие сравнивать строки с учетом языка.
Общая проблема строк JavaScript – они «не в курсе» языка и особенностей стран, где находится посетитель.
При сравнении сравниваются коды символов, а это неправильно, к примеру, в русском языке оказывается, что
Intl.Collator решает все эти проблемы.
P.S. Результат
#разное #Intl #интернационализация
Intl.Collator - конструктор для «сортировщиков», которые представляют собой объекты, позволяющие сравнивать строки с учетом языка.
Общая проблема строк JavaScript – они «не в курсе» языка и особенностей стран, где находится посетитель.
При сравнении сравниваются коды символов, а это неправильно, к примеру, в русском языке оказывается, что
"ё" > "я"
и "а" > "Я"
, хотя всем известно, что я
– последняя буква алфавита и это она должна быть больше любой другой.Intl.Collator решает все эти проблемы.
P.S. Результат
compare
имеет значение 1
(больше), 0
(равно) или -1
(меньше).#разное #Intl #интернационализация
👍18🔥5❤1
Даты, Intl.DateTimeFormat
Первый аргумент – такой же, как и в Collator, а в объекте
Все локали обязаны поддерживать следующие наборы настроек:
- weekday, year, month, day, hour, minute, second
- weekday, year, month, day
- year, month, day
- year, month
- month, day
- hour, minute, second
Если указанный формат не поддерживается, то настройка
#разное #Intl #интернационализация
Первый аргумент – такой же, как и в Collator, а в объекте
options
мы можем определить, какие именно части даты показывать (часы, месяц, год…) и в каком формате.Все локали обязаны поддерживать следующие наборы настроек:
- weekday, year, month, day, hour, minute, second
- weekday, year, month, day
- year, month, day
- year, month
- month, day
- hour, minute, second
Если указанный формат не поддерживается, то настройка
formatMatcher
задаёт алгоритм подбора наиболее близкого формата: basic
– по стандартным правилам и best fit
– по умолчанию, на усмотрение окружения (браузера).#разное #Intl #интернационализация
🔥9👍5