惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Vulnerabilities – Threatpost
有赞技术团队
有赞技术团队
小众软件
小众软件
O
OpenAI News
C
Cyber Attacks, Cyber Crime and Cyber Security
I
Intezer
NISL@THU
NISL@THU
D
Darknet – Hacking Tools, Hacker News & Cyber Security
N
News and Events Feed by Topic
MongoDB | Blog
MongoDB | Blog
阮一峰的网络日志
阮一峰的网络日志
Hacker News: Ask HN
Hacker News: Ask HN
D
Docker
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
A
About on SuperTechFans
Stack Overflow Blog
Stack Overflow Blog
C
CERT Recently Published Vulnerability Notes
L
LINUX DO - 最新话题
Application and Cybersecurity Blog
Application and Cybersecurity Blog
M
MIT News - Artificial intelligence
Blog — PlanetScale
Blog — PlanetScale
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
Hacker News - Newest:
Hacker News - Newest: "LLM"
G
Google Developers Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
Google DeepMind News
Google DeepMind News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
H
Hackread – Cybersecurity News, Data Breaches, AI and More
G
GRAHAM CLULEY
S
Schneier on Security
T
Tor Project blog
Spread Privacy
Spread Privacy
PCI Perspectives
PCI Perspectives
Microsoft Security Blog
Microsoft Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
F
Fortinet All Blogs
L
Lohrmann on Cybersecurity
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
The Exploit Database - CXSecurity.com
TaoSecurity Blog
TaoSecurity Blog
Apple Machine Learning Research
Apple Machine Learning Research
T
Threat Research - Cisco Blogs
T
Troy Hunt's Blog
罗磊的独立博客

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Async/Await in JavaScript: Writing Cleaner Asynchronous Code
Pratham · 2026-05-10 · via DEV Community

Asynchronous code that reads like synchronous code — because sometimes the best upgrade is better syntax.


We've come a long way. Callbacks taught us how JavaScript handles async operations. Promises gave us flat chains and centralized error handling. But let me show you the next evolution:

// Promise chain
getUser(1)
  .then((user) => getOrders(user.id))
  .then((orders) => getShipping(orders[0].id))
  .then((shipping) => console.log(shipping.address))
  .catch((err) => console.log(err));

// Async/await — same logic
async function showShippingAddress() {
  try {
    const user = await getUser(1);
    const orders = await getOrders(user.id);
    const shipping = await getShipping(orders[0].id);
    console.log(shipping.address);
  } catch (err) {
    console.log(err);
  }
}

Enter fullscreen mode Exit fullscreen mode

Look at the async/await version. No .then(). No chaining. No callbacks. It reads exactly like synchronous code — step 1, step 2, step 3 — but it's fully asynchronous under the hood.

When I first saw this in the ChaiCode Web Dev Cohort 2026, I thought it was too good to be true. But it's real, and it's now the standard way to write async JavaScript. Let me break it down.


Why Was Async/Await Introduced?

Promises were a massive improvement over callbacks. But they still have a learning curve. .then() chains, returning values between steps, understanding how .catch() propagates — it's all manageable, but it's not intuitive.

The JavaScript community asked: "What if we could write async code that looks like regular, top-to-bottom, synchronous code?"

That's exactly what async/await is. It was introduced in ES2017 (ES8) as syntactic sugar on top of Promises. It doesn't replace Promises — it uses them. Every async function returns a Promise. Every await unwraps a Promise. It's Promises with a friendlier face.

The Evolution

Callbacks (ES5):
  getUser(1, (err, user) => {
    getOrders(user.id, (err, orders) => {
      getShipping(orders[0].id, (err, ship) => {
        console.log(ship.address);
      });
    });
  });

Promises (ES6):
  getUser(1)
    .then(user => getOrders(user.id))
    .then(orders => getShipping(orders[0].id))
    .then(ship => console.log(ship.address))
    .catch(err => console.log(err));

Async/Await (ES2017):
  const user = await getUser(1);
  const orders = await getOrders(user.id);
  const shipping = await getShipping(orders[0].id);
  console.log(shipping.address);

Same async operations. Each version is cleaner than the last.

Enter fullscreen mode Exit fullscreen mode


How Async Functions Work

An async function is a function declared with the async keyword. Two things happen when you add async:

  1. The function automatically returns a Promise
  2. You're allowed to use the await keyword inside it

Basic Syntax

async function fetchData() {
  return "Hello from async!";
}

// This is identical to:
function fetchData() {
  return Promise.resolve("Hello from async!");
}

Enter fullscreen mode Exit fullscreen mode

Whatever you return from an async function gets wrapped in a resolved Promise automatically.

async function getName() {
  return "Pratham";
}

getName().then((name) => console.log(name)); // "Pratham"

Enter fullscreen mode Exit fullscreen mode

You can also use arrow function syntax:

const getName = async () => {
  return "Pratham";
};

Enter fullscreen mode Exit fullscreen mode

Proof That Async Functions Return Promises

async function example() {
  return 42;
}

const result = example();
console.log(result); // Promise { <fulfilled>: 42 }
console.log(result instanceof Promise); // true

Enter fullscreen mode Exit fullscreen mode

It's a Promise. Always. Even if you return a plain value, it gets wrapped.


The await Keyword

await is the magic word. It pauses the execution of the async function until the Promise it's waiting on settles (fulfills or rejects). Then it unwraps the result and gives you the actual value.

Without await

async function getUser() {
  const response = fetch("https://jsonplaceholder.typicode.com/users/1");
  console.log(response); // Promise { <pending> } — not the data!
}

Enter fullscreen mode Exit fullscreen mode

With await

async function getUser() {
  const response = await fetch(
    "https://jsonplaceholder.typicode.com/users/1",
  );
  const user = await response.json();
  console.log(user.name); // "Leanne Graham" — the actual data!
}

getUser();

Enter fullscreen mode Exit fullscreen mode

await says: "Pause here. Wait for this Promise to resolve. Then give me the value."

Key Rules for await

  1. await can only be used inside async functions (or at the top level of a module)
  2. await pauses the async function, not the entire program — other code keeps running
  3. await works with any Promise — built-in ones like fetch() or your own

await Doesn't Block Everything

This is crucial to understand. When an async function hits await, it pauses that function and gives control back to the rest of the program. Other code continues running.

async function slowTask() {
  console.log("A: Starting slow task...");
  await new Promise((resolve) => setTimeout(resolve, 2000));
  console.log("B: Slow task done!");
}

console.log("1: Before");
slowTask();
console.log("2: After");

Enter fullscreen mode Exit fullscreen mode

Output:

1: Before
A: Starting slow task...
2: After
B: Slow task done!      ← 2 seconds later

Enter fullscreen mode Exit fullscreen mode

"2: After" prints before "B: Slow task done!" because await only pauses the async function, not the calling code.


Async Function Execution Flow

console.log("Start");

async function doWork() {
  console.log("Step 1");
  const data = await fetchSomething();    pauses HERE
  console.log("Step 2:", data);            runs after await resolves
}

doWork();
console.log("End");

Execution:
─────────────────────────────────────────────────
  "Start"          synchronous
  "Step 1"         synchronous (inside async, before await)
  "End"            synchronous (doWork paused at await, control returned)
  ...waiting for fetchSomething()...
  "Step 2: data"   runs when the Promise resolves
─────────────────────────────────────────────────

Key insight: Everything BEFORE the first await runs synchronously.
At the first await, the function pauses and control returns to the caller.

Enter fullscreen mode Exit fullscreen mode


Error Handling with try/catch

With Promises, you use .catch(). With async/await, you use try/catch — the same error handling syntax you use for synchronous code.

Basic Error Handling

async function fetchUser(userId) {
  try {
    const response = await fetch(`https://api.example.com/users/${userId}`);

    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }

    const user = await response.json();
    console.log(`User: ${user.name}`);
  } catch (error) {
    console.log(`Failed to fetch user: ${error.message}`);
  }
}

fetchUser(1);

Enter fullscreen mode Exit fullscreen mode

If anything inside the try block throws an error or if any awaited Promise rejects, execution immediately jumps to the catch block.

With finally

async function loadData() {
  console.log("⏳ Loading...");

  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
    const post = await response.json();
    console.log(`✅ Loaded: ${post.title}`);
  } catch (error) {
    console.log(`❌ Error: ${error.message}`);
  } finally {
    console.log("🏁 Loading complete — cleanup done.");
  }
}

loadData();

Enter fullscreen mode Exit fullscreen mode

finally runs no matter what — perfect for hiding loading spinners, closing connections, or any cleanup.

Handling Multiple Awaits

Each await in a try block is covered by the same catch. If step 2 fails, you don't need a separate error handler:

async function processOrder() {
  try {
    const user = await getUser(1);
    const orders = await getOrders(user.id); // If THIS fails...
    const shipping = await getShipping(orders[0].id);
    console.log(`Shipping to: ${shipping.address}`);
  } catch (error) {
    console.log(`Something failed: ${error.message}`); // ...it's caught HERE
  }
}

Enter fullscreen mode Exit fullscreen mode

Compare this to the Promise version where .catch() at the end catches errors from any step — same behavior, but try/catch reads more naturally.


Promise vs Async/Await — Side by Side

Sequential Operations

// Promise chain
function getProfile() {
  return getUser(1)
    .then((user) => {
      return getAvatar(user.avatarId);
    })
    .then((avatar) => {
      console.log(`Avatar URL: ${avatar.url}`);
    })
    .catch((err) => {
      console.log(err);
    });
}

// Async/await
async function getProfile() {
  try {
    const user = await getUser(1);
    const avatar = await getAvatar(user.avatarId);
    console.log(`Avatar URL: ${avatar.url}`);
  } catch (err) {
    console.log(err);
  }
}

Enter fullscreen mode Exit fullscreen mode

Error Handling

// Promise
fetchData()
  .then((data) => processData(data))
  .then((result) => saveResult(result))
  .catch((err) => console.log("Error:", err));

// Async/await
async function handleData() {
  try {
    const data = await fetchData();
    const result = await processData(data);
    await saveResult(result);
  } catch (err) {
    console.log("Error:", err);
  }
}

Enter fullscreen mode Exit fullscreen mode

Comparison Table

Feature Promises (.then()) Async/Await
Syntax .then() / .catch() chains await + try/catch
Readability Good — but chains can get long Excellent — reads like sync code
Error handling .catch() at the end try/catch — familiar syntax
Debugging Harder — stack traces less clear Easier — breakpoints work normally
Line-by-line Need to follow the chain Each await is its own line
Under the hood Promises Also Promises (syntactic sugar)
When to use Simple chains, .all(), .race() Sequential async, most use cases

Promise vs Async/Await Flow

PROMISE CHAIN:
  getUser(1) ──→ .then() ──→ .then() ──→ .then() ──→ .catch()
                   │            │            │           │
              returns a    returns a    returns a    catches any
              Promise      Promise      Promise      rejection

ASYNC/AWAIT:
  async function() {
    const user = await getUser(1);      ← pause, get value
    const orders = await getOrders();   ← pause, get value
    const ship = await getShipping();   ← pause, get value
    console.log(ship.address);          ← use the value
  }

Same thing. Different syntax. Async/await just reads top-to-bottom.

Enter fullscreen mode Exit fullscreen mode


Practical Patterns

Pattern 1: Fetching Data from a Real API

async function displayUser() {
  try {
    const response = await fetch(
      "https://jsonplaceholder.typicode.com/users/1",
    );
    const user = await response.json();

    console.log(`Name: ${user.name}`);
    console.log(`Email: ${user.email}`);
    console.log(`City: ${user.address.city}`);
  } catch (error) {
    console.log("Failed to fetch user:", error.message);
  }
}

displayUser();

Enter fullscreen mode Exit fullscreen mode

Pattern 2: Sequential Operations

async function morningRoutine() {
  const coffee = await makeCoffee(); // Wait for coffee first
  const breakfast = await cookBreakfast(); // Then cook breakfast
  const news = await fetchNews(); // Then fetch news

  console.log(`Enjoying ${coffee} with ${breakfast} while reading ${news}`);
}

Enter fullscreen mode Exit fullscreen mode

Each step waits for the previous one. Order matters here.

Pattern 3: Parallel Operations with Promise.all()

Sometimes steps are independent — they don't depend on each other. Running them sequentially wastes time:

// ❌ Sequential — slow (3 seconds total)
async function loadDashboard() {
  const user = await fetchUser(); // 1 second
  const posts = await fetchPosts(); // 1 second
  const notifications = await fetchNotifications(); // 1 second
  // Total: 3 seconds 😴
}

// ✅ Parallel — fast (1 second total)
async function loadDashboard() {
  const [user, posts, notifications] = await Promise.all([
    fetchUser(), // 1 second ─┐
    fetchPosts(), // 1 second  ├─ all run simultaneously
    fetchNotifications(), // 1 second ─┘
  ]);
  // Total: ~1 second 🚀
}

Enter fullscreen mode Exit fullscreen mode

Promise.all() runs all three fetches at the same time and waits for all of them to finish. If any one fails, the entire Promise.all() rejects.

Pattern 4: Async in Arrow Functions

const getUser = async (id) => {
  const response = await fetch(`https://api.example.com/users/${id}`);
  return response.json();
};

const user = await getUser(1);

Enter fullscreen mode Exit fullscreen mode


Let's Practice: Hands-On Assignment

Part 1: Basic Async/Await

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async function countdown() {
  console.log("3...");
  await delay(1000);
  console.log("2...");
  await delay(1000);
  console.log("1...");
  await delay(1000);
  console.log("🚀 Go!");
}

countdown();

Enter fullscreen mode Exit fullscreen mode

Part 2: Fetch Real Data

async function getPost() {
  try {
    const response = await fetch(
      "https://jsonplaceholder.typicode.com/posts/1",
    );
    const post = await response.json();

    console.log(`Title: ${post.title}`);
    console.log(`Body: ${post.body}`);
  } catch (error) {
    console.log("Error:", error.message);
  }
}

getPost();

Enter fullscreen mode Exit fullscreen mode

Part 3: Sequential vs Parallel

const fakeAPI = (name, ms) =>
  new Promise((resolve) => {
    setTimeout(() => resolve(`${name} loaded`), ms);
  });

// Sequential — runs one after another
async function sequential() {
  console.time("Sequential");
  const a = await fakeAPI("Users", 1000);
  const b = await fakeAPI("Posts", 1000);
  const c = await fakeAPI("Comments", 1000);
  console.log(a, b, c);
  console.timeEnd("Sequential"); // ~3 seconds
}

// Parallel — runs all at once
async function parallel() {
  console.time("Parallel");
  const [a, b, c] = await Promise.all([
    fakeAPI("Users", 1000),
    fakeAPI("Posts", 1000),
    fakeAPI("Comments", 1000),
  ]);
  console.log(a, b, c);
  console.timeEnd("Parallel"); // ~1 second
}

sequential();
// parallel();  // Try this one too!

Enter fullscreen mode Exit fullscreen mode

Part 4: Error Handling

async function riskyFetch() {
  try {
    const response = await fetch("https://invalid-url.example.com");
    const data = await response.json();
    console.log("Data:", data);
  } catch (error) {
    console.log("Caught an error:", error.message);
  } finally {
    console.log("Fetch attempt complete.");
  }
}

riskyFetch();

Enter fullscreen mode Exit fullscreen mode


Key Takeaways

  1. Async/await is syntactic sugar over Promises. It doesn't replace them — it makes them easier to write and read.
  2. async makes a function return a Promise. await pauses the function until a Promise resolves, then gives you the value.
  3. await only pauses the async function, not the entire program. Other code continues running while the function waits.
  4. Error handling uses try/catch — the same familiar syntax from synchronous JavaScript. Add finally for cleanup.
  5. Use Promise.all() for independent operations that can run in parallel. Use sequential await when each step depends on the previous one.

Wrapping Up

Async/await is the final piece of the async JavaScript puzzle. Callbacks showed us the concept. Promises gave us structure. Async/await gave us readability. The fact that you can write asynchronous code that looks and reads like regular, top-to-bottom JavaScript — with proper error handling and no nesting — is genuinely one of the best things about modern JavaScript.

I'm learning all of this through the ChaiCode Web Dev Cohort 2026 under Hitesh Chaudhary and Piyush Garg. The journey from callbacks → Promises → async/await has been one of the most satisfying progressions in the cohort. Each one builds on the last, and by the time you reach async/await, it all just clicks.

Connect with me on LinkedIn or visit PrathamDEV.in. More articles coming as the journey continues.

Happy coding! 🚀


Written by Pratham Bhardwaj | Web Dev Cohort 2026, ChaiCode