Suggest an editImprove this articleRefine the answer for “Callback function”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**A callback function is a function passed as an argument to another function so that it runs later: after some event happens or an operation finishes.** Put simply: "I am handing you a function, call it when you are ready." This works because functions in JavaScript are first-class objects, so they can be passed around like ordinary values. The receiving function does not call the callback immediately, it stores it and invokes it at the right moment: when a timer fires, a request completes or the user clicks. `setTimeout`, `addEventListener`, `fetch().then()` and almost all asynchrony are built on this. The main problem is deep nesting, known as callback hell, which `Promise` and `async/await` solve. ```javascript function greet(callback) { console.log('Getting ready to say hello...'); callback('Oleh'); } greet((name) => console.log(`Hello, ${name}!`)); ``` **Key point:** a callback is a function passed as an argument and called later, when the right moment arrives.Shown above the full answer for quick recall.Answer (EN)Image**A callback function is a function passed as an argument to another function so that it runs later, after some event happens or an operation finishes.** Put simply: "I am handing you a function, call it when you are ready." ## Theory ### TL;DR - A callback is a function passed as an argument that the receiving function calls at the right moment. - This works because functions in JavaScript are first-class objects and can be passed as values. - A callback can be named or anonymous, an arrow function in particular. - A callback is not necessarily asynchronous: `array.map(fn)` calls it synchronously, `setTimeout(fn)` does not. - `setTimeout`, `addEventListener` and `fetch().then()` are all built on callbacks. - Deep nesting of callbacks is called callback hell, and `Promise` plus `async/await` cure it. ### Quick example ```javascript function sayHello(name) { console.log(`Hello, ${name}!`); } function greet(callback) { console.log('Getting ready to say hello...'); callback('Oleh'); } greet(sayHello); // Output: // Getting ready to say hello... // Hello, Oleh! ``` What happens: 1. `sayHello` is the **callback** passed into `greet`; 2. `greet` calls it from inside itself; 3. two lines are printed to the console, in the order the code runs. Note that `sayHello` is passed to `greet` **without parentheses**. `greet(sayHello())` would call the function immediately and pass its result, that is, `undefined`. ### How it works - JavaScript accepts a callback as a **value**, since functions here are first-class objects. - The receiving function **does not call it immediately**, it **stores it for a later call**. - When the right moment arrives (the timer fired, the request finished, the event happened), the engine **calls that function**. A callback does not have to be named, an anonymous function is often passed instead: ```javascript setTimeout(() => { console.log('Two seconds have passed'); }, 2000); ``` Here `() => console.log(...)` is the callback function, and it will be called **in two seconds**, not right away. ### Callbacks in real situations **1. An event handler.** Here the browser calls the callback when the user clicks: ```javascript button.addEventListener('click', () => { console.log('Button clicked!'); }); ``` **2. Loading data.** The `.then()` callbacks are called **after** the asynchronous request completes: ```javascript fetch('/user') .then(response => response.json()) .then(data => console.log(data)); ``` **3. A step in an algorithm.** A callback is not necessarily tied to asynchrony, it can simply be a way to plug your own logic in: ```javascript function calculate(a, b, callback) { const result = a + b; callback(result); } calculate(2, 3, (sum) => { console.log('Result:', sum); }); ``` ### The callback hell problem When there are too many callbacks, the code becomes **nested and unreadable**: ```javascript getUser(id, user => { getPosts(user, posts => { getComments(posts, comments => { console.log('Done!'); }); }); }); ``` This is called **callback hell**: every next step shifts the code further to the right, error handling is duplicated at each level, and the sequence of actions becomes hard to follow. ### How to get rid of the nesting Promises appeared to avoid these infernal nestings: ```javascript getUser(id) .then(getPosts) .then(getComments) .then(console.log); ``` And then `async/await`, which gives asynchronous code the look of ordinary sequential code: ```javascript const user = await getUser(id); const posts = await getPosts(user); const comments = await getComments(posts); console.log('Done!'); ``` A simple analogy for an interview: > Imagine you order a pizza and say: "Call me when it is ready." That call is the callback. **Summary:** | Term | Description | | --- | --- | | **Callback function** | A function passed into another function to be run later | | **When it is called** | After an event, after an operation completes, or on a condition | | **Usage examples** | `setTimeout`, `addEventListener`, `fetch().then()` | | **The problem** | Deep nesting (callback hell) | | **Modern alternatives** | `Promise`, `async/await` | ### Common mistakes - **Passing a call instead of a function.** `setTimeout(fn(), 1000)` runs `fn` immediately and hands the timer its result. The correct form is `setTimeout(fn, 1000)`. - **Assuming every callback is asynchronous.** `array.forEach(fn)` and `array.map(fn)` call the callback synchronously, right now, and defer nothing. - **Losing `this`.** A regular function used as a callback gets its own `this`. Use an arrow function or `bind`. - **Ignoring errors.** In the error-first style the first argument is the error: `(err, data) => { if (err) ... }`. Skip it and failures are lost silently. - **Calling the callback twice.** Without a `return` after an error the function keeps going and calls the callback again, which breaks all the logic above it. - **Building deep pyramids.** Three or more levels of nesting is a signal to rewrite the code with `Promise` or `async/await`.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.