JS Objects & Async
Для чего придумали промисы?
Проблема до промисов: «ад колбэков» — вложенные callback при асинхронных операциях, сложно обрабатывать ошибки и композировать несколько шагов.
Что даёт Promise:
- Единый контракт будущего значения:
pending→fulfilledилиrejected. - Цепочки
.then/.catch/.finallyбез глубокой вложенности. - Стандартное пробрасывание ошибок вниз по цепочке до ближайшего
catch. - Композиция:
Promise.all,race,allSettledи т.д.
Эволюция: промисы стали основой async/await (синтаксический сахар поверх thenable), что улучшило читаемость последовательного асинхронного кода.
Для собеса: промисы формализуют асинхронность, интегрируются с microtask queue и современным API (
fetch).
Как избежать ссылочной зависимости при копировании объекта?
Объекты и массивы передаются по ссылке. Чтобы получить независимую копию — нужно явно клонировать.
const original = { a: 1, nested: { b: 2 } };
// ❌ Присваивание — это просто вторая ссылка
const bad = original;
bad.a = 99; // original.a тоже стал 99
// ✅ Поверхностная копия — вложенные объекты всё ещё общие
const shallow = { ...original };
shallow.nested.b = 99; // original.nested.b тоже изменился ❌
// ✅ Глубокая копия — полностью независимая
const deep = structuredClone(original);
deep.nested.b = 99; // original.nested.b не изменился ✅
// Альтернатива через JSON (с потерями — см. таблицу ниже)
const deep2 = JSON.parse(JSON.stringify(original));Что сериализуется
| Тип данных | JSON.parse(JSON.stringify()) | structuredClone |
|---|---|---|
string, number, boolean | ✅ без потерь | ✅ без потерь |
null | ✅ остаётся null | ✅ остаётся null |
Array, Object | ✅ рекурсивно | ✅ рекурсивно |
undefined | ❌ поле удаляется | ✅ сохраняется |
function | ❌ поле удаляется | ❌ бросает ошибку |
Symbol | ❌ поле удаляется | ❌ бросает DataCloneError |
Date | ⚠️ превращается в строку ISO | ✅ остаётся Date |
Map, Set | ❌ Map → {}, Set → [] | ✅ полная копия |
ArrayBuffer, Blob | ❌ теряются | ✅ копируется |
Infinity, NaN | ❌ превращаются в null | ✅ сохраняются |
| Циклические ссылки | ❌ бросает ошибку | ✅ обрабатывает |
| DOM-узлы | ❌ теряются | ❌ бросает ошибку |
Тонкости shallow/deep copy и семантика значений/ссылок — см. value-types.
См. также
- event-loop — как промисы связаны с microtask queue
- value-types — примитивы, ссылки, копирование
- rest-graphql — работа с API