Callback functions are a quite powerful and handy way of using code with Javascript. The definition is simple, is a function used inside another one, also known as higher order functions, you might have used a few in your projects without being too aware, every time you use map, filter, forEach, etc you are taking advantage of callbacks, they really help extend and reuse code in different ways.

Basic example

const foo = () => "function x";

const bar = callback => `I am function bar, returning ${callback()}`;

console.log(bar(foo));

// I am function bar, returning function foo

We can immediately start thinking about going further and do crazy stuff.

   
    .......

    const z = callback => console.log(`${callback}, inside z`)

    z(bar(foo));

    // I am function bar, returning function foo, inside z
  

A more practical example

Building a mini calculator

    const add = (a, b) => a + b;
    const multiply = (a, b) => a * b;

    const calc = (num1, num2, callback) => {
      return callback(num1, num2)
    };

    const resultAdd = calc(10, 3, add);

    const resultMult = calc(5, 2, multiply);

    console.log(resultAdd);
    console.log(resultMult);

    // 13
    // 10

  

Let's explore a very common scenario, were we have multiple api calls coming from different places which might cause some issues, depending on how long they take to finalize.

    const users = ['Rolando', 'Bob', 'Richard'];

    const addUser = (newUser) => {
      setTimeout(() => {
        users.push(newUser);
      }, 200);
    };

    const getUsers = () => {
      setTimeout(() => {
        console.log(users);
      }, 100);
    };
 
    addUser("Ana");
    console.log(getUsers());

    // ['Rolando', 'Bob', 'Richard'] 
    
    * Ana is missing here
    
  

In this example, we are adding a new user to our users array, to later console them, but wait, the last user ( Anna ) is not showing, this is not good, because as you can see, getting the users list is faster than adding one, this is a common problem we face due to Javascript being asynchronous, fortunately we can handle this with a callback function.

    const users = ['Rolando', 'Bob', 'Richard'];

    const addUser = (newUser, callback) => {
      setTimeout(() => {
        users.push(newUser);
        callback();
      }, 200);
    };

    const getUsers = () => {
      setTimeout(() => {
        console.log(users);
      }, 100);
    };

    // First add user to databse then execute getUsers.

    addUser("Anna", getUsers);

    // ['Rolando', 'Bob', 'Richard', 'Anna'];

  

Callbacks can rescue us from troubles or simply makes us writte more flexible code, is a very good thing to learn and understand.