Asynchronous JavaScript Basics: From Callback Hell to Promises
JavaScript is a single-threaded programming language, meaning it can only execute one operation at a time. This would be a serious problem during network requests (e.g., API calls) or file system operations, as network latency would cause the entire user interface to freeze.
To handle this problem, JavaScript uses asynchronous operations. In the past, this was exclusively solved with callback functions. However, when multiple dependent asynchronous requests had to be handled, the code quickly became unreadable; the industry calls this "Callback Hell".
The Revolution of Promise Objects
To eliminate Callback Hell, the Promise object was introduced. A Promise is a representation of a future value that can exist in one of three states:
- Pending: The operation is still in progress.
- Fulfilled: The operation completed successfully (it returned with a value).
- Rejected: The operation failed due to an error.
const loadData = () => {
return new Promise((resolve, reject) => {
const isSuccess = true;
setTimeout(() => {
if (isSuccess) {
resolve({ user: "Peter", status: "active" });
} else {
reject("A server error occurred!");
}
}, 1500);
});
};
loadData()
.then(data => console.log("Data successfully requested:", data))
.catch(error => console.error("Error:", error));