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 into another function so that it can be called later, once that function has finished its work.** Callbacks let you pass behaviour rather than just data, and they are used to run an action after an event, an operation or an asynchronous process: loading data, a timer, a click. ```javascript function fetchData(callback) { setTimeout(() => { const data = 'Data from the server'; callback(data); // call the function we were given }, 1000); } fetchData(result => console.log(result)); // "Data from the server" ``` **Key point:** a callback is a way to pass behaviour around and to control the order in which code runs, especially in asynchronous operations.Shown above the full answer for quick recall.Answer (EN)Image**A callback function is a function passed as an argument into another function, which calls it later, once it has finished its own work.** Callbacks are normally used to run an action after an event, an operation or an asynchronous process, for example after data has loaded, a timer has fired or a click has happened. ## Theory ### TL;DR - A callback is a function argument that is called by the function you handed it to, not by your own code. - This works because functions in JavaScript are first class values: they can be passed around and returned. - Callbacks can be synchronous (`map`, `filter`, `forEach`) or asynchronous (`setTimeout`, event handlers, requests). - Pass a reference to the function, not its call: `setTimeout(fn, 100)`, not `setTimeout(fn(), 100)`. - Deeply nested callbacks turn into callback hell, which Promises and `async/await` are there to cure. ### Quick example ```javascript function fetchData(callback) { setTimeout(() => { const data = 'Data from the server'; callback(data); // call the function we were given }, 1000); } fetchData(result => console.log(result)); // "Data from the server" ``` `fetchData` knows nothing about what will be done with the result: it receives that part of the behaviour from outside. ### Why it works: functions as values In JavaScript a function is an ordinary value, so it can be assigned to a variable, put in an array or passed to another function. A function that accepts or returns another function is called a higher-order function, and the function that is passed in is the callback. ```javascript const numbers = [1, 2, 3]; // map is the higher-order function, the arrow function inside is the callback const doubled = numbers.map(n => n * 2); // [2, 4, 6] ``` ### Synchronous and asynchronous callbacks A synchronous callback runs immediately, within the same function call. An asynchronous one is queued and runs later, once the call stack is empty. ```javascript // synchronous: runs before the next line [1, 2, 3].forEach(n => console.log(n)); // asynchronous: runs after all synchronous code setTimeout(() => console.log('later'), 0); console.log('now'); // console order: 1, 2, 3, now, later ``` ### Error handling: the error-first style Node.js established a convention: the first parameter of a callback is the error, and the data follows it. That way the caller can handle a failure in the same place where it receives the result. ```javascript function loadUser(id, callback) { setTimeout(() => { if (!id) { callback(new Error('id is required')); return; } callback(null, { id, name: 'Maria' }); }, 100); } loadUser(7, (err, user) => { if (err) { console.error(err.message); return; } console.log(user.name); // Maria }); ``` ### Callback hell and the modern alternative When one asynchronous operation depends on another, callbacks start nesting inside each other and the code drifts to the right like a staircase. That is callback hell: hard to read, and even harder to handle errors in. ```javascript loadUser(7, (err, user) => { loadOrders(user.id, (err, orders) => { loadItems(orders[0].id, (err, items) => { console.log(items); // nesting grows with every step }); }); }); ``` The modern answer is Promises and `async/await`: the same sequence is written flat, and errors are caught by a single `try/catch`. ```javascript async function showItems() { try { const user = await loadUser(7); const orders = await loadOrders(user.id); const items = await loadItems(orders[0].id); console.log(items); } catch (err) { console.error(err.message); } } ``` ### Common mistakes - Passing the result of a call instead of the function itself: `setTimeout(sayHi(), 100)` runs `sayHi` right away and hands the timer `undefined`. The correct form is `setTimeout(sayHi, 100)`. - Expecting a value received inside an asynchronous callback to be available right after the function call: it only appears once the callback actually runs. - Ignoring the first error argument in error-first callbacks and carrying on with empty data. - Calling the callback twice, both on success and on failure, because the `return` after the error branch was forgotten. - Losing `this` when an object method is passed as a callback: `element.addEventListener('click', obj.handler)` calls the method with a different `this`. An arrow function or `bind` fixes it. - Building deeply nested callbacks where Promises or `async/await` would do the job.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.