В шпаргалке собраны основные методы Web Storage API (localStorage и sessionStorage) для работы с простым key–value хранилищем на стороне клиента. Показано, как сохранять, читать и удалять данные, сериализовывать объекты, очищать хранилище и реагировать на изменения состояния между вкладками с помощью события storage.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤19🔥10🤝9👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Здесь разбираются замыкания, this, области видимости, асинхронность, прототипы и др. важные темы. Отличный репозиторий, если хочешь не просто писать код, а понимать, почему он работает именно так. Полезно для роста и закрепления знаний.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19❤12🔥9🤝1
Генерация UUID без сторонних библиотек!
Уникальные ID нужны везде: ключи для данных, идентификаторы сущностей, корреляционные ID, маркеры транзакций. В JS есть нативное решение —
Самый простой кейс — получить уникальный идентификатор для сущности, события или записи:
Каждый вызов возвращает новый UUID.
Иногда нужно быстро создать пачку ID — например, для тестов, сидирования данных или моков:
Такой подход не требует состояния и имеет пренебрежимо малую вероятность коллизий.
UUID удобно сразу добавлять в структуру данных — например, при создании объектов в памяти или перед сохранением в БД:
UUID часто используют для трассировки запросов и событий в логах — особенно в асинхронном коде и микросервисах:
Такой ID позволяет связать все логи одного запроса, даже если он проходит через несколько уровней или сервисов.
🔥 UUID — это идентификаторы, а не security-токены для авторизации. Отлично подходят для логирования, тестовых данных и структур хранения
📣 JS Ready | #практика
Уникальные ID нужны везде: ключи для данных, идентификаторы сущностей, корреляционные ID, маркеры транзакций. В JS есть нативное решение —
crypto.randomUUID().Самый простой кейс — получить уникальный идентификатор для сущности, события или записи:
const id = crypto.randomUUID();
console.log("UUID:", id);
Каждый вызов возвращает новый UUID.
Иногда нужно быстро создать пачку ID — например, для тестов, сидирования данных или моков:
const ids = Array.from({ length: 5 }, () => crypto.randomUUID());
console.log("Список UUID:", ids);Такой подход не требует состояния и имеет пренебрежимо малую вероятность коллизий.
UUID удобно сразу добавлять в структуру данных — например, при создании объектов в памяти или перед сохранением в БД:
const user = { name: "Alice", id: crypto.randomUUID() };
console.log("Пользователь:", user);UUID часто используют для трассировки запросов и событий в логах — особенно в асинхронном коде и микросервисах:
function withCorrelationId(fn) {
const correlationId = crypto.randomUUID();
return fn(correlationId);
}
withCorrelationId((cid) => {
console.log(`[${cid}] start request`);
// бизнес-логика
console.log(`[${cid}] end request`);
});Такой ID позволяет связать все логи одного запроса, даже если он проходит через несколько уровней или сервисов.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍8❤7🤝1
Как корректно показывать относительное время в интерфейсе?
Очень частая задача: показать относительное время, “только что”, “3 часа назад”, “через 2 дня”.
В JS есть нативный и локализованный API -
Он сам знает грамматику языка и формы слов:
Поддерживает
Идеально ложится в логику UI:
🔥
📣 JS Ready | #совет
Очень частая задача: показать относительное время, “только что”, “3 часа назад”, “через 2 дня”.
В JS есть нативный и локализованный API -
Intl.RelativeTimeFormat:new Intl.RelativeTimeFormat(locale, options);
Он сам знает грамматику языка и формы слов:
rtf.format(-1, 'hour'); // «час назад»
rtf.format(-2, 'hour'); // «2 часа назад»
Поддерживает
second | minute | hour | day | week | month | year и работает одинаково во всех локалях:new Intl.RelativeTimeFormat('en').format(-1, 'day'); // yesterday
new Intl.RelativeTimeFormat('de').format(3, 'day'); // in 3 TagenИдеально ложится в логику UI:
const diff = Math.round((date - Date.now()) / 60000);
rtf.format(diff, 'minute');
Intl.RelativeTimeFormat — нативный способ показывать относительное время корректно, локализованно и без библиотек.Please open Telegram to view this post
VIEW IN TELEGRAM
👍20❤7🔥7🤝3
This media is not supported in your browser
VIEW IN TELEGRAM
Postman — инструмент для работы с API прямо из VS Code: отправка запросов, просмотр ответов, работа с headers, body, токенами и коллекциями. Удобно тестировать эндпоинты, проверять ответы и разбираться в API ещё до интеграции во фронт. Экономит время и помогает быстрее понять, что приходит с сервера.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤21🔥13👍7🤝2
Шпаргалка по работе с состоянием в JavaScript без мутаций. Примеры показывают, как аккуратно изменять объекты и массивы, создавая новые структуры данных вместо изменения существующих. Такой подход упрощает отслеживание изменений, снижает риск непреднамеренных изменений данных и делает код более понятным при дальнейшей поддержке.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤8🔥7🤝4
Please open Telegram to view this post
VIEW IN TELEGRAM
❤19👍11🔥9
Параллельные запросы без падения всего приложения — Promise.allSettled!
Очень часто нужно выполнить несколько async-задач параллельно - запросы, загрузки, вычисления.
Обычно используют
Если хотя бы один промис упал, теряется результат всех остальных, даже успешных. Для реального кода это почти всегда не то, что нужно.
Результат всегда предсказуемый, у каждого элемента есть статус и данные:
Это идеально ложится на UI, отчёты и фоновые задачи:
🔥
📣 JS Ready | #совет
Очень часто нужно выполнить несколько async-задач параллельно - запросы, загрузки, вычисления.
Обычно используют
Promise.all, но у него есть проблема:await Promise.all(requests); // один reject и всё падает
Если хотя бы один промис упал, теряется результат всех остальных, даже успешных. Для реального кода это почти всегда не то, что нужно.
Promise.allSettled дожидается всех промисов, независимо от ошибок:await Promise.allSettled(requests);
Результат всегда предсказуемый, у каждого элемента есть статус и данные:
{ status: 'fulfilled', value }
{ status: 'rejected', reason }Это идеально ложится на UI, отчёты и фоновые задачи:
const ok = results.filter(r => r.status === 'fulfilled');
const failed = results.filter(r => r.status === 'rejected');
Promise.allSettled - отличный вариант, когда важен результат каждой задачиPlease open Telegram to view this post
VIEW IN TELEGRAM
🔥14❤8👍8🤝3
В этой статье:
• Знакомство с библиотекой Three.js;
• Cоздание сцены, камеры, освещения, отрисовка, масштабирование и управление визуализацией;
• Построение логики игры;
• Чёткие объяснения каждого шага — от сетапа до ООП-архитектуры игры;🔊 Прочитать статью можно на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤9🔥6🤝3😁1
Итерация по объекту как по массиву пар с Object.entries()!
Если нужны только собственные enumerable строковые ключи — удобнее сразу использовать
Распространённый кейс — валидации перед запуском бизнес-логики (например, запретить undefined в значениях):
Map оправдан, когда нужны частые
Нормализация объекта в массив DTO для API или записи в БД:
🔥 Такой подход делает обработку объекта структурной и удобной для масштабирования логики.
📣 JS Ready | #практика
for...in перебирает enumerable строковые ключи, включая унаследованные — такие итерации требуют фильтрации через Object.hasOwn() или hasOwnProperty(). Если нужны только собственные enumerable строковые ключи — удобнее сразу использовать
Object.entries().Object.entries() возвращает пары own enumerable string-keyed свойств (без Symbol, без non-enumerable):const user = {
name: "Alex",
age: 30,
role: "developer"
};
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}Распространённый кейс — валидации перед запуском бизнес-логики (например, запретить undefined в значениях):
Object.entries(user).forEach(([k, v]) => {
if (v === undefined) {
throw new Error(`Значение "${k}" не должно быть undefined`);
}
});Map оправдан, когда нужны частые
set/delete, map.size, не-строковые ключи или словарная структура без ограничений объекта:const userMap = new Map(Object.entries(user));
console.log(userMap.get("role"));
Нормализация объекта в массив DTO для API или записи в БД:
const dto = Object.entries(user).map(([field, value]) => ({
field,
value,
updatedAt: new Date().toISOString()
}));
console.log(dto);Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥8❤7🤝2
Например, HTTP/1.1 использует постоянные соединения, HTTP/2 умеет мультиплексировать запросы в одном TCP-канале, а HTTP/3 работает поверх QUIC и UDP.
На картинке — наглядная эволюция HTTP от первых версий до современных стандартов.
Сохрани, чтобы не забыть!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍10🤝10
Как убрать повторные запросы без флагов и состояний?
Очень частая нужно не трогать API повторно, если данные уже запрашивались.
Это можно сделать просто, используя поведение Map:
Если значение уже есть, оно сразу возвращается, если нет - создаётся, кладётся в кеш и тут же возвращается:
Фишка в том, что в кеше можно хранить Promise, и тогда несколько вызовов одновременно получат один и тот же запрос, без дублей:
🔥 Пригодится при кешировании API-запросов, дедупликации параллельных вызовов, state-менеджменте без лишней синхронизации.
📣 JS Ready | #совет
Очень частая нужно не трогать API повторно, если данные уже запрашивались.
Это можно сделать просто, используя поведение Map:
cache.get(id) ?? cache.set(id, value).get(id)
Если значение уже есть, оно сразу возвращается, если нет - создаётся, кладётся в кеш и тут же возвращается:
const getConfig = (key) =>
cache.get(key) ??
cache.set(key, loadConfig(key)).get(key);
Фишка в том, что в кеше можно хранить Promise, и тогда несколько вызовов одновременно получат один и тот же запрос, без дублей:
getUser(42);
getUser(42);
// fetch выполнится один раз
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤9🔥7🤝1
Парсим курсы валют через API!
Работа с внешними API — базовая часть клиентской разработки: виджеты, расчёты, мониторинг, простая аналитика.
Сначала формируем запрос к API и получаем HTTP-ответ. На этом этапе важно проверить статус ответа, прежде чем пытаться читать данные:
Теперь выносим работу с JSON и обработку ошибок в отдельный слой. Такой подход упрощает расширение логики и повторное использование функции:
Вызываем функцию и работаем с результатом. Перед доступом к данным проверяем, что запрос завершился успешно:
Для более гибкого сценария используем массив кодов валют и проходимся по нему циклом. Это удобно, когда список валют динамический или приходит из конфигурации:
🔥 В итоге получаем аккуратный API-клиент для браузера или Node.js, который легко масштабируется: кэширование, сравнение курсов, алерты, интеграция в UI или ботов.
📣 JS Ready | #практика
Работа с внешними API — базовая часть клиентской разработки: виджеты, расчёты, мониторинг, простая аналитика.
Сначала формируем запрос к API и получаем HTTP-ответ. На этом этапе важно проверить статус ответа, прежде чем пытаться читать данные:
async function fetchRates(base) {
const url = `https://open.er-api.com/v6/latest/${base}`;
const res = await fetch(url);
if (!res.ok) {
throw new Error(`HTTP error: ${res.status}`);
}
return res;
}Теперь выносим работу с JSON и обработку ошибок в отдельный слой. Такой подход упрощает расширение логики и повторное использование функции:
async function getRates(base = "USD") {
try {
const res = await fetchRates(base);
const data = await res.json();
if (data.result !== "success" || !data.rates) {
throw new Error("Invalid API response");
}
return data;
} catch (err) {
console.error("Ошибка получения курсов:", err.message);
return null;
}
}Вызываем функцию и работаем с результатом. Перед доступом к данным проверяем, что запрос завершился успешно:
getRates("USD").then(r => {
if (!r) return;
console.log("Базовая валюта:", r.base_code);
console.log("EUR:", r.rates.EUR);
console.log("GBP:", r.rates.GBP);
console.log("JPY:", r.rates.JPY);
});Для более гибкого сценария используем массив кодов валют и проходимся по нему циклом. Это удобно, когда список валют динамический или приходит из конфигурации:
getRates("EUR").then(r => {
if (!r) return;
["USD", "GBP", "JPY", "CNY"].forEach(code => {
console.log(`${code}:`, r.rates?.[code] ?? "—");
});
});Please open Telegram to view this post
VIEW IN TELEGRAM
❤16👍9🔥7🤝2