Fundamentals 23 min read

Unlock Asynchronous Power: Master Callback Functions in 3 Minutes

This article explains what callback functions are, how they enable asynchronous programming across languages, demonstrates their implementation with JavaScript, C/C++, Python and HTML examples, and discusses practical use‑cases, advantages, pitfalls like callback hell, and modern alternatives such as Promises and async/await.

Deepin Linux
Deepin Linux
Deepin Linux
Unlock Asynchronous Power: Master Callback Functions in 3 Minutes

Overview of Callback Functions

A callback is a function passed as an argument to another function and invoked automatically after a specific event or operation completes. It enables asynchronous programming, event‑driven designs, and decouples logic.

Callback : function supplied to another function.

Asynchronous programming : code that does not block the main thread.

Event‑driven : execution triggered by external events.

How Callbacks Work

The caller executes its core logic, then calls the supplied callback(s) to perform additional work without modifying the caller’s code.

JavaScript Example – Shopping Cart

// Define callbacks
function updateCartTotal() {
    console.log('Cart total updated');
}

function showSuccessMessage() {
    console.log('Product added successfully');
}

// Simulate adding a product
function addToCart(product, cb1, cb2) {
    console.log('Added ' + product + ' to cart');
    if (typeof cb1 === 'function') cb1();
    if (typeof cb2 === 'function') cb2();
}

addToCart('Apple', updateCartTotal, showSuccessMessage);

The addToCart function receives the product name and two callbacks, checks their types, and invokes them after the simulated addition.

Calling Conventions and Pitfalls

When callbacks cross language boundaries, the caller and callee must agree on calling convention (e.g., __stdcall, __cdecl), parameter types, count, and return value. Mismatches cause undefined behavior or crashes.

Implementation Mechanisms

Function Pointers (C/C++)

// Declaration
return_type (*callback_name)(parameter_list);

// Example
int (*callback)(int, int);
int add(int a, int b) { return a + b; }
callback = add; // assign function address

Functor Objects (C++)

class Callback {
public:
    ReturnType operator()(ParamList) {
        // function body
    }
};

Anonymous Functions / Lambdas

#include <iostream>
#include <vector>

void forEach(const std::vector<int>& v, void(*cb)(int)) {
    for (int i : v) cb(i);
}

int main() {
    std::vector<int> v = {1,2,3,4,5};
    forEach(v, [](int i){ std::cout << i << " "; });
}

Common Application Scenarios

Event handling (clicks, key presses, network responses).

Asynchronous operations (file I/O, AJAX, timers).

Data processing (sorting, filtering, mapping).

Plugin development (WordPress, jQuery, Vue.js).

Asynchronous Operations in JavaScript

// setTimeout example
setTimeout(function() {
    console.log('Welcome after 3 seconds');
}, 3000);

// jQuery AJAX example
$.ajax({
    url: 'https://api.example.com/users',
    type: 'GET',
    dataType: 'json',
    success: function(data) {
        // handle data
    },
    error: function() {
        console.log('Request failed');
    }
});

Event‑Driven Programming (HTML/JS)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Button Click Example</title>
</head>
<body>
    <button id="myButton">Click Me</button>
    <script>
        document.getElementById('myButton').addEventListener('click', function() {
            alert('Button clicked');
        });
    </script>
</body>
</html>

Standard Library Callback – C qsort

#include <stdio.h>
#include <stdlib.h>

int int_cmp(const void *a, const void *b) {
    return (*(int *)a - *(int *)b);
}

int main() {
    int arr[] = {5,2,8,1,9};
    size_t n = sizeof(arr)/sizeof(arr[0]);
    qsort(arr, n, sizeof(arr[0]), int_cmp);
    for (size_t i = 0; i < n; ++i) printf("%d ", arr[i]);
    printf("
");
    return 0;
}

Vue.js Lifecycle Hook

new Vue({
    el: '#app',
    data: { message: 'Hello, Vue!' },
    mounted: function() {
        console.log('Component mounted');
        // Example AJAX request
        this.$http.get('/data').then(response => {
            this.message = response.data;
        });
    }
});

Advantages and Challenges

Advantages : increased flexibility, code reuse, reduced coupling, easier modularization.

Challenges : callback hell, harder debugging, potential performance overhead. Modern alternatives such as Promise and async/await flatten nested callbacks.

// Promise chain example
function getData1() {
    return new Promise((resolve, reject) => {
        $.ajax({url:'https://api.example.com/data1',type:'GET',success:resolve,error:reject});
    });
}
function getData2(id) {
    return new Promise((resolve, reject) => {
        $.ajax({url:`https://api.example.com/data2?id=${id}`,type:'GET',success:resolve,error:reject});
    });
}
function getData3(key) {
    return new Promise((resolve, reject) => {
        $.ajax({url:`https://api.example.com/data3?key=${key}`,type:'GET',success:resolve,error:reject});
    });
}

getData1()
    .then(d1 => getData2(d1.id))
    .then(d2 => getData3(d2.key))
    .then(d3 => { /* handle final data */ })
    .catch(err => console.log('Request failed', err));
// async/await equivalent
async function getData() {
    try {
        const d1 = await $.ajax({url:'https://api.example.com/data1',type:'GET'});
        const d2 = await $.ajax({url:`https://api.example.com/data2?id=${d1.id}`,type:'GET'});
        const d3 = await $.ajax({url:`https://api.example.com/data3?key=${d2.key}`,type:'GET'});
        // handle final data
    } catch (e) {
        console.log('Request failed', e);
    }
}
getData();

Concrete Examples

Python Sorting with Callback

students = [
    {'name': 'Alice', 'age': 20},
    {'name': 'Bob',   'age': 18},
    {'name': 'Charlie','age': 22}
]

def get_age(s):
    return s['age']

sorted_by_age = sorted(students, key=get_age)
print(sorted_by_age)

def get_name(s):
    return s['name']

sorted_by_name_desc = sorted(students, key=get_name, reverse=True)
print(sorted_by_name_desc)

Simulated Event Listener (JavaScript)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Game Init Example</title>
</head>
<body>
    <button id="startButton">Start Game</button>
    <script>
        function loadGameScene() { console.log('Scene loaded'); }
        function initializeCharacter() { console.log('Character initialized'); }
        function addEventListener(el, type, cb) {
            if (el.addEventListener) el.addEventListener(type, cb);
            else if (el.attachEvent) el.attachEvent('on' + type, cb);
        }
        var btn = document.getElementById('startButton');
        addEventListener(btn, 'click', function() {
            loadGameScene();
            initializeCharacter();
        });
    </script>
</body>
</html>
JavaScriptAsynchronousprogramming fundamentalsevent-drivencallbackC++
Deepin Linux
Written by

Deepin Linux

Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.