Что такое callback?
Callback — это функция, которую мы передаём другой функции, чтобы она вызвала её, когда будет готов результат.
При этом сам callback не делает код асинхронным — он просто может быть вызван асинхронно.
Как callback связан с асинхронностью?
- JS вызывает функцию, которая инициирует асинхронную операцию (setTimeout, обработчик клика, сетевой запрос).
- Эта операция выполняется во внешнем окружении (например, в браузере).
- Когда операция завершена, окружение помещает callback в очередь задач.
- Event Loop проверяет стек вызовов. Если стек пуст, можно взять задачу из очереди.
- Callback перемещается из очереди в стек вызовов и выполняется движком JS.
Проблемы callback-подхода (callback hell)
1. Вложенность
Когда одна асинхронная операция зависит от результата другой, колбэки начинают вкладываться друг в друга.
Такой код сложно писать и поддерживать.
Пример с четырьмя уровнями вложенности:
getUser(id, function(user) { // 1-й уровень
getOrders(user.id, function(orders) { // 2-й уровень
getOrderDetails(orders[0], function(info) { // 3-й уровень
getDeliveryStatus(info.orderId, function(status) { // 4-й уровень
console.log("Статус доставки:", status);
});
});
});
});
2. Потеря контроля (inversion of control)
Inversion of control — это когда кто-то другой решает, когда и как вызвать наш callback.
Мы не контролируем:
- сколько раз вызовут callback,
- когда его вызовут,
- какие данные передадут,
- вызовут ли его вообще.
Это проблема, потому что нарушается надёжность и предсказуемость выполнения.
Пример:
function unreliable(fn) {
// Чужая библиотека. Мы не контролируем её поведение.
setTimeout(() => fn("первый вызов"), 100);
setTimeout(() => fn("второй вызов"), 200); // баг: двойной вызов
}
unreliable(result => {
console.log("Callback получил:", result);
});
В итоге callback’и сложно контролировать и сложно связывать между собой.
Именно из-за этих проблем позже появились Promises и async/await.
#async #callback #callback_hell #hello_developer_2_0