JavaScript Promises Explained for Beginners
JavaScript is single-threaded, meaning it can only do one thing at a time. But what if you need to fetch data from an API , read a file , or wait for a timer without freezing your app? This is where promises come in. 🧠 What Problem Do Promises Solve? Before promises, we used callbacks for async tasks: ```js id="cb1" fetchData(function(data) { processData(data, function(result) { console.log(result); }); }); ❌ Callback hell → hard to read, hard to maintain Promises simplify this by representing a **future value**: > A promise is like a placeholder for a value that **may not be available yet**. --- ## ⏳ Promise States A promise can be in **three states**: 1. **Pending** – initial state, waiting for the result 2. **Fulfilled** – operation succeeded, value available 3. **Rejected** – operatio
JavaScript is single-threaded, meaning it can only do one thing at a time. But what if you need to fetch data from an API, read a file, or wait for a timer without freezing your app?
This is where promises come in.
🧠 What Problem Do Promises Solve?
Before promises, we used callbacks for async tasks:
fetchData(function(data) {
processData(data, function(result) {
console.log(result);
});
});
`❌ Callback hell → hard to read, hard to maintain
Promises simplify this by representing a **future value**:
> A promise is like a placeholder for a value that **may not be available yet**.
---
## ⏳ Promise States
A promise can be in **three states**:
1. **Pending** – initial state, waiting for the result
2. **Fulfilled** – operation succeeded, value available
3. **Rejected** – operation failed, error available
```id="viz1"
Pending → Fulfilled or Rejected`
Enter fullscreen mode
Exit fullscreen mode
## ⚙️ Basic Promise Lifecycle
```js id="promise1"
const promise = new Promise((resolve, reject) => {
const success = true;
if (success) {
resolve("Task completed");
} else {
reject("Task failed");
}
});
promise
.then(result => console.log(result)) // handles success
.catch(error => console.log(error)); // handles failure
`### Output if success = true:
```plaintext
Task completed`
Enter fullscreen mode
Exit fullscreen mode
### Output if success = false:
`Task failed`
Enter fullscreen mode
Exit fullscreen mode
## 🔄 Promise Chaining
Promises can be chained to run multiple async tasks sequentially:
```js id="chain1"
fetchData()
.then(data => processData(data))
.then(result => console.log(result))
.catch(err => console.error(err));
`✔ Cleaner than nested callbacks
✔ Easier to read and maintain
---
## 📊 Callback vs Promise
| Feature | Callback | Promise |
| -------------- | ------------ | -------------- |
| Readability | Low (nested) | High (linear) |
| Error handling | Hard | Easy (`catch`) |
| Async flow | Nested | Chained |
| Future value | No | Yes |
---
## 🛠️ Real-World Example
```js id="real1"
function fetchUser(userId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (userId === 1) {
resolve({ id: 1, name: "Rahul" });
} else {
reject("User not found");
}
}, 1000);
});
}
fetchUser(1)
.then(user => console.log(user.name)) // Rahul
.catch(err => console.log(err));`
Enter fullscreen mode
Exit fullscreen mode
## 🧩 Visualizing Promise Lifecycle
`Promise created → pending
↓
(resolve) fulfilled → .then runs
(reject) rejected → .catch runs`
Enter fullscreen mode
Exit fullscreen mode
## 🧠 Key Takeaways
- Promises represent a value in the future
- They prevent callback hell
- .then() handles success, .catch() handles errors
- Can be chained for sequential async operations
## 🚀 Final Thoughts
Promises are the foundation of modern asynchronous JavaScript. Once you master them, you’ll be ready for:
- Async/await syntax
- Complex async workflows
- Clean, readable, maintainable code
fetchData(function(data) {
processData(data, function(result) {
console.log(result);
});
});
`❌ Callback hell → hard to read, hard to maintain
Promises simplify this by representing a **future value**:
> A promise is like a placeholder for a value that **may not be available yet**.
---
## ⏳ Promise States
A promise can be in **three states**:
1. **Pending** – initial state, waiting for the result
2. **Fulfilled** – operation succeeded, value available
3. **Rejected** – operation failed, error available
```id="viz1"
Pending → Fulfilled or Rejected`
Enter fullscreen mode
Exit fullscreen mode
## ⚙️ Basic Promise Lifecycle
```js id="promise1"
const promise = new Promise((resolve, reject) => {
const success = true;
if (success) {
resolve("Task completed");
} else {
reject("Task failed");
}
});
promise
.then(result => console.log(result)) // handles success
.catch(error => console.log(error)); // handles failure
`### Output if success = true:
```plaintext
Task completed`
Enter fullscreen mode
Exit fullscreen mode
### Output if success = false:
`Task failed`
Enter fullscreen mode
Exit fullscreen mode
## 🔄 Promise Chaining
Promises can be chained to run multiple async tasks sequentially:
```js id="chain1"
fetchData()
.then(data => processData(data))
.then(result => console.log(result))
.catch(err => console.error(err));
`✔ Cleaner than nested callbacks
✔ Easier to read and maintain
---
## 📊 Callback vs Promise
| Feature | Callback | Promise |
| -------------- | ------------ | -------------- |
| Readability | Low (nested) | High (linear) |
| Error handling | Hard | Easy (`catch`) |
| Async flow | Nested | Chained |
| Future value | No | Yes |
---
## 🛠️ Real-World Example
```js id="real1"
function fetchUser(userId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (userId === 1) {
resolve({ id: 1, name: "Rahul" });
} else {
reject("User not found");
}
}, 1000);
});
}
fetchUser(1)
.then(user => console.log(user.name)) // Rahul
.catch(err => console.log(err));`
Enter fullscreen mode
Exit fullscreen mode
## 🧩 Visualizing Promise Lifecycle
`Promise created → pending
↓
(resolve) fulfilled → .then runs
(reject) rejected → .catch runs`
Enter fullscreen mode
Exit fullscreen mode
## 🧠 Key Takeaways
- Promises represent a value in the future
- They prevent callback hell
- .then() handles success, .catch() handles errors
- Can be chained for sequential async operations
## 🚀 Final Thoughts
Promises are the foundation of modern asynchronous JavaScript. Once you master them, you’ll be ready for:
- Async/await syntax
- Complex async workflows
- Clean, readable, maintainable code
DEV Community
https://dev.to/souvik_blog_b790df30e8dea/javascript-promises-explained-for-beginners-4okkSign in to highlight and annotate this article

Conversation starters
Daily AI Digest
Get the top 5 AI stories delivered to your inbox every morning.
More about
availablefeature
Improved markdown quality, code intelligence for 248 languages, and more in Kreuzberg v4.7.0
Kreuzberg v4.7.0 is here. Kreuzberg is a Rust-core document intelligence library that works with Python, TypeScript/Node.js, Go, Ruby, Java, C#, PHP, Elixir, R, C, and WASM. We’ve added several features, integrated OpenWEBUI, and made a big improvement in quality across all formats. There is also a new markdown rendering layer and new HTML output, which we now support. And much more (which you can find in our the release notes ). The main highlight is code intelligence and extraction. Kreuzberg now supports 248 formats through our tree-sitter-language-pack library . This is a step toward making Kreuzberg an engine for agents too. You can efficiently parse code, allowing direct integration as a library for agents and via MCP. Agents work with code repositories, review pull requests, index c

research-llm-apis 2026-04-04
Release: research-llm-apis 2026-04-04 I'm working on a major change to my LLM Python library and CLI tool. LLM provides an abstraction layer over hundreds of different LLMs from dozens of different vendors thanks to its plugin system, and some of those vendors have grown new features over the past year which LLM's abstraction layer can't handle, such as server-side tool execution. To help design that new abstraction layer I had Claude Code read through the Python client libraries for Anthropic, OpenAI, Gemini and Mistral and use those to help craft curl commands to access the raw JSON for both streaming and non-streaming modes across a range of different scenarios. Both the scripts and the captured outputs now live in this new repo. Tags: llm , apis , json , llms

Truckloads of food are being wasted because computers won’t approve them
Modern food systems may look stable on the surface, but they are increasingly dependent on digital systems that can quietly become a major point of failure. Today, food must be “recognized” by databases and automated platforms to be transported, sold, or even released, meaning that if systems go down, food can effectively become unusable—even when it’s physically available.
Knowledge Map
Connected Articles — Knowledge Graph
This article is connected to other articles through shared AI topics and tags.
More in Releases

Improved markdown quality, code intelligence for 248 languages, and more in Kreuzberg v4.7.0
Kreuzberg v4.7.0 is here. Kreuzberg is a Rust-core document intelligence library that works with Python, TypeScript/Node.js, Go, Ruby, Java, C#, PHP, Elixir, R, C, and WASM. We’ve added several features, integrated OpenWEBUI, and made a big improvement in quality across all formats. There is also a new markdown rendering layer and new HTML output, which we now support. And much more (which you can find in our the release notes ). The main highlight is code intelligence and extraction. Kreuzberg now supports 248 formats through our tree-sitter-language-pack library . This is a step toward making Kreuzberg an engine for agents too. You can efficiently parse code, allowing direct integration as a library for agents and via MCP. Agents work with code repositories, review pull requests, index c

Truckloads of food are being wasted because computers won’t approve them
Modern food systems may look stable on the surface, but they are increasingly dependent on digital systems that can quietly become a major point of failure. Today, food must be “recognized” by databases and automated platforms to be transported, sold, or even released, meaning that if systems go down, food can effectively become unusable—even when it’s physically available.

I Put an LLM Inside the Linux Kernel Scheduler. Here's What Happened.
A few weeks ago, I did something that probably shouldn't work. I replaced the CPU scheduling algorithm in my Linux kernel with calls to an AI model. As on-device LLM inference capabilities grow, I am curious about its potential as a CPU scheduler. Maybe in the future, tweaking a laptop's performance is a matter of adjusting the system prompt 🤷♂️ What Is a CPU Scheduler? CPU Scheduler is an operating system component that decides which task or process gets to use the CPU at a particular time. Linux's default scheduler is called CFS (Completely Fair Scheduler). It's an algorithm that tries to give every process a fair share of CPU time, weighted by priority. It makes decisions in microseconds, fully algorithmic. The Idea Two things that made this feel worth trying. First, sched_ext landed



Discussion
Sign in to join the discussion
No comments yet — be the first to share your thoughts!