Clean Markup

Writing Clean Asynchronous Code with Async and Await

Writing Clean Asynchronous Code with Async and Await

Deeply nested callbacks and long .then() chains can make asynchronous control flow and error handling difficult to reason about. Built on top of native JavaScript Promises, async and await allow you to write asynchronous fetch requests that read like synchronous top-to-bottom code—and handle both network and JSON parsing errors in a single try / catch block.

Example

// Promise chain
function loadUser(id) {
  return fetch("/api/users/" + id)
    .then(function (res) { return res.json(); })
    .catch(function (err) { console.error(err); });
}

// Clean async/await equivalent
async function loadUserClean(id) {
  try {
    const res = await fetch("/api/users/" + id);
    return await res.json();
  } catch (err) {
    console.error(err);
  }
}

Input : Asynchronous REST API endpoints
Output : Sequential and parallel async / await functions with explicit HTTP status verification.

Implementation

async function fetchArticleWithComments(articleSlug) {
  try {
    // Run independent requests in parallel using Promise.all
    const responses = await Promise.all([
      fetch("/api/articles/" + encodeURIComponent(articleSlug)),
      fetch("/api/articles/" + encodeURIComponent(articleSlug) + "/comments")
    ]);

    const articleRes = responses[0];
    const commentsRes = responses[1];

    if (!articleRes.ok) {
      throw new Error("Failed to load article: HTTP " + articleRes.status);
    }

    const article = await articleRes.json();
    const comments = commentsRes.ok ? await commentsRes.json() : [];

    return {
      article: article,
      comments: comments
    };
  } catch (error) {
    console.error("Error loading article view:", error.message);
    return null;
  }
}

Main Point: Avoid awaiting independent network requests one after another in a serial sequence; wrap independent Promises in await Promise.all([...]) so they fetch concurrently.

Credits

Photo by Markus Spiske

← Home