Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Understanding and Applying JavaScript Promises for Asynchronous Operations

Tech 1

A Promise is a built-in JavaScript object introduced in ECMAScript 2015 that represents the eventual outcome of an asynchronous operation — either a resolved value or a reason for rejection.

Each Promise instance transitions through exactly one of three mutually exclusive states:

  • Pending: The initial state; neither fulfilled nor rejected.
  • Fulfilled: The operation completed successfully, and a value is available.
  • Rejected: The operation failed, and an error or reason is provided.
const task = new Promise((onSuccess, onFailure) => {
  // Simulate asynchronous work (e.g., API call, timeout)
  setTimeout(() => {
    const success = Math.random() > 0.3;
    if (success) {
      onSuccess('Operation succeeded');
    } else {
      onFailure(new Error('Operation timed out'));
    }
  }, 1000);
});

Consuming Promises

Once created, a Promise is consumed using .then() for success handling and .catch() for error propagation:

task
  .then(result => {
    console.log('✅', result);
    return result.toUpperCase();
  })
  .catch(err => {
    console.error('❌', err.message);
  });

The .then() method accepts up to two functions: the first handles fulfillment, the second (optional) handles rejection. How ever, prefer chaining .catch() at the end for centralized error handling.

Chaining Promises

Each .then() returns a new Promise, enabling sequential composition. Return values from one handler become the input to the next, while returning another Promise defers execution until that Promise settles:

fetch('/api/data')
  .then(response => response.json())
  .then(data => {
    console.log('Parsed data:', data);
    return processUserData(data);
  })
  .then(processed => {
    console.log('Processed:', processed);
  })
  .catch(e => {
    console.error('Chain interrupted:', e);
  });

Concurrent Execution with Promise.all

To execute multiple independant asynchronous tasks in parallel and wait for all to complete, use Promise.all. It resolves when all input Promises fulfill, or rejects immediately upon the first rejection:

const apiCalls = [
  fetch('/api/users'),
  fetch('/api/posts'),
  fetch('/api/comments')
];

Promise.all(apiCalls)
  .then(responses => Promise.all(responses.map(r => r.json())))
  .then(([users, posts, comments]) => {
    renderDashboard({ users, posts, comments });
  })
  .catch(error => {
    showGlobalError(`Failed to load dashboard: ${error.message}`);
  });

For cases where partial failure is acceptable, consider Promise.allSettled, which waits for all Promises to settle (fulfill or reject) and returns an array of result descriptors.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.