Шпаргалка по работе с состоянием в 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
В шпаргалке собраны основные приёмы управления выполнением функций. Рассматриваются способы явного задания контекста с помощью call, apply и bind, а также инструменты для отмены асинхронных операций через AbortController и AbortSignal. Материал охватывает практические примеры, связанные с контролем контекста, аргументов и жизненного цикла выполнения.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12❤8👍7🤝1
This media is not supported in your browser
VIEW IN TELEGRAM
IntelliCode — улучшает автодополнение в VS Code: предлагает варианты на основе контекста, типа данных и того, что ты уже написал. Удобно в больших проектах, где важно быстрее находить нужные методы и не отвлекаться.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍8🤝8❤1
Проверка наличия элемента!
Когда нужно понять, есть ли значение в массиве, раньше почти всегда делали с
Проблема в том, что он возвращает индекс или
Здесь ошибка не в синтаксисе, а в модели мышления,
А отрицание читается ровно так, как написано:
🔥 Код короче, шансов на логическую ошибку практически нет, поэтому
📣 JS Ready | #совет
Когда нужно понять, есть ли значение в массиве, раньше почти всегда делали с
indexOf.Проблема в том, что он возвращает индекс или
-1, а -1 в JS - truthy, из-за чего легко написать логически неверную проверку:if (![1, 2].indexOf(3)) {
// выглядит приемлемо, но работает неправильно
}Здесь ошибка не в синтаксисе, а в модели мышления,
indexOf вообще не про boolean.includes решает эту проблему на уровне API: он возвращает true или false, без неявных преобразований.[1, 2].includes(2); // true
[1, 2].includes(3); // false
А отрицание читается ровно так, как написано:
if (![1, 2].includes(3)) {
console.log('Not found');
}includes отличный выбор для проверок, а indexOf стоит оставлять только для получения индекса.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍10❤9
This media is not supported in your browser
VIEW IN TELEGRAM
Это полноценный справочник с чёткими объяснениями, примерами кода и интерактивными демо. Каждая тема сопровождается примерами, которые можно сразу попробовать и понять, как именно работает та или иная конструкция. Очень полезно и новичкам, и тем, кто хочет освежить знания или быстро найти пример по конкретной задаче.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤10🔥9
Пишем консольную мини-игру «Быки и коровы»!
Для тех, кто не знает или забыл правила: игрок угадывает 4-значное число без повторов. Бык - цифра угадана и стоит на своём месте. Корова - цифра есть в числе, но позиция неверная.
Подключаем консольный ввод и генерируем секретное число: 4 разные цифры в случайном порядке:
Здесь важно, что число создаётся один раз и не меняется до конца игры.
Главная часть игры: сравниваем ввод игрока с секретом и считаем совпадения.
Если цифра совпала по индексу - это бык, если просто присутствует - корова.
Каждый ход - это запрос числа, валидация и подсчёт результата:
Принимаем только корректный ввод, ровно 4 цифры, иначе ход повторяется.
Если все цифры угаданы на своих местах, игра заканчивается, иначе показываем подсказку:
Финал и точка входа максимально простые:
🔥 Эта игра помогает попрактиковать работу с состоянием, пользовательским вводом и управлением асинхронным потоком
📣 JS Ready | #практика
Для тех, кто не знает или забыл правила: игрок угадывает 4-значное число без повторов. Бык - цифра угадана и стоит на своём месте. Корова - цифра есть в числе, но позиция неверная.
Подключаем консольный ввод и генерируем секретное число: 4 разные цифры в случайном порядке:
const rl = require("readline").createInterface({
input: process.stdin, output: process.stdout
});
const secret = [...new Set(
Array.from({ length: 10 }, (_, i) => i)
)].sort(() => 0.5 - Math.random()).slice(0, 4).join("");Здесь важно, что число создаётся один раз и не меняется до конца игры.
Главная часть игры: сравниваем ввод игрока с секретом и считаем совпадения.
const score = g => {
let b = 0, c = 0;
for (let i = 0; i < 4; i++)
secret[i] === g[i] ? b++ : secret.includes(g[i]) && c++;
return [b, c];
};Если цифра совпала по индексу - это бык, если просто присутствует - корова.
Каждый ход - это запрос числа, валидация и подсчёт результата:
const turn = () => rl.question("Число: ", g => {
if (!/^\d{4}$/.test(g)) return turn();
const [b, c] = score(g);Принимаем только корректный ввод, ровно 4 цифры, иначе ход повторяется.
Если все цифры угаданы на своих местах, игра заканчивается, иначе показываем подсказку:
if (b === 4) return win();
console.log(`🐂 ${b} | 🐄 ${c}`);
turn();
});
Финал и точка входа максимально простые:
const win = () => {
console.log(`🏆 Победа! Было: ${secret}`);
rl.close();
};
turn();Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍9🔥8
This media is not supported in your browser
VIEW IN TELEGRAM
Это необычное руководство по JS, построенное так, чтобы его было легко читать и понимать. Материал объясняет базовые концепции языка простым языком, с примерами и объяснениями. Ресурс подойдёт для знакомства с синтаксисом или для повторения основ без излишне сложной теории.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14❤10👍8
Дополнительные функции обратного вызова!
Иногда функция должна быть универсальной и вызывать колбэк только если он передан, при этом не увеличивая код проверками:
В JS это делается напрямую через optional chaining, без условий и лишней логики:
Если колбэк не передан, код просто пропускается, если передан — вызывается как обычная функция:
🔥 Такой приём позволяет проектировать API с опциональным поведением без перегрузок функций и условий.
📣 JS Ready | #совет
Иногда функция должна быть универсальной и вызывать колбэк только если он передан, при этом не увеличивая код проверками:
if (callback) {
callback(data);
}В JS это делается напрямую через optional chaining, без условий и лишней логики:
callback?.(data);
Если колбэк не передан, код просто пропускается, если передан — вызывается как обычная функция:
fetchData('/api/user');
fetchData('/api/user', data => console.log(data));Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤9🤝8
This media is not supported in your browser
VIEW IN TELEGRAM
Markdown Preview Enhanced — расширяет стандартный предпросмотр Markdown в VS Code. Поддерживает диаграммы, формулы, графики, Mermaid, подсветку кода, экспорт в PDF и HTML. Сразу видишь, как будет выглядеть README, документация или статья, без внешних инструментов и лишних шагов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤6🤝5