Image by Author

JavaScript Asynchronous Programming

Callbacks, Promises, and Async/Await

Yeran Kods
Nerd For Tech
Published in
4 min readDec 18, 2023

--

JavaScript, a versatile and widely-used programming language, supports various mechanisms for handling asynchronous operations. In this article, we’ll explore three key concepts: callbacks, promises, and async/await, providing clear examples to help you understand and apply these concepts effectively.

Callbacks: The Foundation of Asynchronous JavaScript

Callbacks are functions passed as arguments to other functions and are executed once the operation is complete. In asynchronous JavaScript, callbacks are pivotal for handling asynchronous tasks like fetching data from an API.

Example: Fetching Data with Callbacks

function fetchDataWithCallback(url, callback) {
setTimeout(function () {
let responseData = { message: "Data successfully fetched!" };
callback(null, responseData);
}, 1000);
}

function handleData(error, data) {
if (error) {
console.error("Error:", error);
} else {
console.log("Response Data:", data.message);
}
}

fetchDataWithCallback("https://example.com/api/data", handleData);

In this example, fetchDataWithCallback simulates an asynchronous operation and invokes the provided callback function (handleData) with the response data or an error.

Promises: A Cleaner Approach

Promises provide a cleaner and more structured way to handle asynchronous operations, improving code readability and maintainability. A promise represents the eventual completion or failure of an asynchronous operation, allowing developers to attach callbacks for success or failure.

Example: Fetching Data with Promises

function fetchData(url) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
let responseData = { message: "Data successfully fetched!" };
resolve(responseData);
}, 1000);
});
}

fetchData("https://example.com/api/data")
.then(function (data) {
console.log("Response Data:", data.message);
})
.catch(function (error) {
console.error("Error:", error);
});

In this example, the fetchData function returns a promise, allowing the use of the then and catch methods to handle success and failure, respectively.

Async/Await: A Synchronous-looking Asynchronous Code

Async/await is a modern and more readable approach to handling asynchronous operations. It is built on top of promises, providing a synchronous-looking syntax for asynchronous code.

Example: Fetching Data with Async/Await

function fetchData(url) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
let responseData = { message: "Data successfully fetched!" };
resolve(responseData);
}, 1000);
});
}

async function fetchDataAsync(url) {
try {
const data = await fetchData(url);
console.log("Response Data:", data.message);
} catch (error) {
console.error("Error:", error);
}
}

fetchDataAsync("https://example.com/api/data");

In this example, the fetchDataAsync function uses the async keyword, allowing the use of await within the function body. This makes the asynchronous code appear more like traditional synchronous code.

Understanding callbacks, promises, and async/await is crucial for mastering asynchronous JavaScript. Whether you’re handling simple UI interactions or complex server requests, these concepts empower you to write efficient and readable code. By grasping these fundamentals, you’ll be well-equipped to tackle asynchronous programming challenges in your JavaScript projects.

ExtraKnowledge#1 — Object Literals

In JavaScript, the {} curly braces are used to define an object literal. An object is a collection of key-value pairs, where each key is a string (or a Symbol) and each value can be any valid JavaScript expression, including other objects.

Example:

let responseData = { message: "Data successfully fetched!" };

Here, you are creating an object named responseData with a single property message. The colon : is used to assign the value to the key. In this case, the key is "message" and the value is the string "Data successfully fetched!"

You can access the value of the message property using dot notation:

console.log(responseData.message); // Output: Data successfully fetched!

Or you can use square bracket notation:

console.log(responseData['message']); // Output: Data successfully fetched!

Objects in JavaScript are versatile and are often used to represent data structures. They can contain various data types, including other objects, arrays, functions, and more.

ExtraKnowledge#2— let vs var vs const

Current standard for defining variables in modern JavaScript is to use let and const instead of var. Here’s why?

Brief overview of each:

  1. let: It allows you to declare variables that can be reassigned. Variables declared with let are block-scoped, meaning they are only available within the block, statement, or expression where they are defined.
let myVariable = 10;

2. const: It is used to declare variables that cannot be reassigned. The value of a const variable remains constant throughout the code. Like let, const is block-scoped.

const myConstant = 20;

3.var: It was traditionally used in JavaScript to declare variables. However, variables declared with var are function-scoped (or globally-scoped if declared outside any function), and they have some quirks that can lead to unexpected behavior. With the introduction of let and const in ECMAScript 6 (ES6), the use of var is generally discouraged in modern JavaScript.

var oldVariable = 30;

For modern JavaScript development, it’s recommended to use let for variables that may be reassigned and const for variables that should remain constant. This helps improve code readability and avoid unintentional variable reassignments. Additionally, using let and const provides better scoping behavior compared to var.

Hope you learned something new.❤️

Connect with me via;

--

--

Yeran Kods
Nerd For Tech

Interest is what inspires.🌍 | New articles every week !