Lädt...


🔧 Deep Dive into JavaScript Promises: Patterns and Best Practices


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

JavaScript promises are a powerful tool for handling asynchronous operations. They represent a value that may be available now, or in the future, or never. Understanding how to effectively use promises can significantly improve the quality and readability of your code. This article will explore the intricacies of JavaScript promises, common patterns, and best practices.

What is a Promise?

A promise is an object representing the eventual completion or failure of an asynchronous operation. It allows you to attach handlers for the eventual success or failure of that operation.

Basic Promise Syntax

let promise = new Promise(function(resolve, reject) {
  // executor (the producing code, "singer")
});

States of a Promise

  • Pending: Initial state, neither fulfilled nor rejected.
  • Fulfilled: The operation completed successfully.
  • Rejected: The operation failed.

Creating a Promise

A promise is created using the new Promise constructor which takes a function (executor) with two arguments: resolve and reject.

let promise = new Promise((resolve, reject) => {
  setTimeout(() => resolve("done"), 1000);
});

Consuming Promises

You consume promises using then, catch, and finally methods.

promise
  .then(result => console.log(result)) // "done" after 1 second
  .catch(error => console.error(error))
  .finally(() => console.log("Promise finished"));

Common Patterns with Promises

1. Chaining Promises

Promise chaining is a pattern where each then returns a new promise, making it easy to perform a series of asynchronous operations sequentially.

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => {
    console.log(data);
    return fetch('https://api.example.com/other-data');
  })
  .then(response => response.json())
  .then(otherData => console.log(otherData))
  .catch(error => console.error('Error:', error));

2. Error Handling

Proper error handling in promises ensures that you can catch errors at any point in the chain.

promise
  .then(result => {
    throw new Error("Something went wrong");
  })
  .catch(error => {
    console.error(error.message);
  });

3. Parallel Execution with Promise.all

When you need to run multiple asynchronous operations in parallel, use Promise.all.

Promise.all([
  fetch('https://api.example.com/data1'),
  fetch('https://api.example.com/data2')
])
  .then(responses => Promise.all(responses.map(res => res.json())))
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

4. Promise.race

Promise.race returns a promise that resolves or rejects as soon as one of the promises in the iterable resolves or rejects.

Promise.race([
  new Promise(resolve => setTimeout(resolve, 100, 'one')),
  new Promise(resolve => setTimeout(resolve, 200, 'two'))
])
  .then(value => console.log(value)); // "one"

Best Practices with Promises

1. Always Return a Promise

When working within a then handler, always return a promise. This ensures that the next then in the chain waits for the returned promise to resolve.

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => {
    return fetch('https://api.example.com/other-data');
  })
  .then(response => response.json())
  .then(otherData => console.log(otherData));

2. Use catch for Error Handling

Always use catch at the end of your promise chain to handle errors.

fetch('https://api.example.com/data')
  .then(response => response.json())
  .catch(error => console.error('Fetch error:', error));

3. Use finally for Cleanup

Use finally to execute code that should run regardless of whether the promise is fulfilled or rejected.

promise
  .then(result => console.log(result))
  .catch(error => console.error(error))
  .finally(() => console.log('Cleanup'));

4. Avoid the Promise Constructor Anti-Pattern

Don't use the promise constructor when you can use existing promise-based APIs.

Anti-Pattern:

new Promise((resolve, reject) => {
  fs.readFile('file.txt', (err, data) => {
    if (err) reject(err);
    else resolve(data);
  });
});

Better:

const {promises: fsPromises} = require('fs');
fsPromises.readFile('file.txt');

Examples of Promises in Real-World Scenarios

Example 1: Fetching Data from an API

function fetchData() {
  return fetch('https://jsonplaceholder.typicode.com/todos/1')
    .then(response => {
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      return response.json();
    })
    .then(data => console.log(data))
    .catch(error => console.error('Fetch error:', error));
}

fetchData();

Example 2: Sequential API Calls

function fetchUserAndPosts() {
  return fetch('https://jsonplaceholder.typicode.com/users/1')
    .then(response => response.json())
    .then(user => {
      console.log(user);
      return fetch(`https://jsonplaceholder.typicode.com/posts?userId=${user.id}`);
    })
    .then(response => response.json())
    .then(posts => console.log(posts))
    .catch(error => console.error('Error:', error));
}

fetchUserAndPosts();

Promises are a cornerstone of modern JavaScript, enabling developers to handle asynchronous operations with greater ease and readability. By understanding the various patterns and best practices, you can write more efficient and maintainable code. Remember to always handle errors properly, return promises in then handlers, and utilize Promise.all and Promise.race for parallel and competitive asynchronous tasks. With these techniques, you'll be well-equipped to tackle complex asynchronous programming challenges.

...

🔧 Deep Dive into JavaScript Promises: Patterns and Best Practices


📈 71.75 Punkte
🔧 Programmierung

🔧 DESIGN PATTERNS : A Deep Dive into Common Design Patterns


📈 50.84 Punkte
🔧 Programmierung

🔧 Understanding JavaScript Inheritance: A Deep Dive into Prototypal and Constructor Patterns


📈 46.24 Punkte
🔧 Programmierung

🔧 Async Made Easy: A Deep Dive into JavaScript Callbacks, Promises, and Async/Await


📈 45.66 Punkte
🔧 Programmierung

🔧 Async Made Easy: A Deep Dive into JavaScript Callbacks, Promises, and Async/Await


📈 45.66 Punkte
🔧 Programmierung

🔧 Flow & Cadence Best Practices, Patterns, and Anti-Patterns


📈 40.6 Punkte
🔧 Programmierung

🔧 A Deep Dive into `useEffect`: Best Practices for React Developers


📈 38.39 Punkte
🔧 Programmierung

📰 Unveiling Mobile App Secrets: A 6-Month Deep Dive into Surprising Behavior Patterns


📈 37.99 Punkte
📰 IT Security Nachrichten

📰 Maximizing Efficiency in AI Training: A Deep Dive into Data Selection Practices and Future Directions


📈 35.52 Punkte
🔧 AI Nachrichten

🔧 A Deep Dive Into Recommendation Algorithms With Netflix Case Study and NVIDIA Deep Learning Technology


📈 35.16 Punkte
🔧 Programmierung

🔧 Error Handling for Large Rust Projects - A Deep Dive into GreptimeDB's Practices


📈 33.85 Punkte
🔧 Programmierung

🔧 Mastering JavaScript Promises: Best Practices for Clean and Efficient Code


📈 33.75 Punkte
🔧 Programmierung

🎥 Deep dive into Flutter deep linking


📈 33.49 Punkte
🎥 Video | Youtube

🔧 Deep Dive into apple-app-site-association file: Enhancing Deep Linking on iOS


📈 33.49 Punkte
🔧 Programmierung

🔧 Deep Dive into apple-app-site-association file: Enhancing Deep Linking on iOS


📈 33.49 Punkte
🔧 Programmierung

🔧 How JavaScript's console.log() Surprised Me: A Deep Dive into Its Hidden Gems and Unexpected Behaviors


📈 33.39 Punkte
🔧 Programmierung

🔧 A deep dive into converting between strings and numbers in JavaScript


📈 33.39 Punkte
🔧 Programmierung

🔧 A Deep Dive into Self-Referencing Objects and Circular References in JavaScript


📈 33.39 Punkte
🔧 Programmierung

🔧 Decoding the Conversation: A Deep Dive into Request and Response Objects in JavaScript


📈 33.39 Punkte
🔧 Programmierung

🔧 Deep Dive into JavaScript Closures: How and When to Use Them


📈 33.39 Punkte
🔧 Programmierung

🔧 Unraveling JavaScript: A Deep Dive into Hoisting, Temporal Dead Zone, and Variable States


📈 33.39 Punkte
🔧 Programmierung

🔧 Day 13: Deep Dive into Object Properties, Getters & Setters, and Lexical Scope in JavaScript 🎉


📈 33.39 Punkte
🔧 Programmierung

🔧 Day 2: Deep Dive into JavaScript Data Types, Strict Mode, and Basic Operations


📈 33.39 Punkte
🔧 Programmierung

📰 Cybersecurity Reloaded: Best Practices | Digital Legal Academy Deep Dive Session #2


📈 32.36 Punkte
📰 IT Security Nachrichten

🔧 Design Patterns in JavaScript: Creational Patterns


📈 32.27 Punkte
🔧 Programmierung

🔧 JavaScript Promises: Best Practices & Keeping Your Code Clean


📈 32.09 Punkte
🔧 Programmierung

🔧 Mastering ES2019: A Deep Dive into Five Key JavaScript Features


📈 31.72 Punkte
🔧 Programmierung

🔧 Deep Dive into Data structures using Javascript - Priority Queue


📈 31.72 Punkte
🔧 Programmierung

🔧 Deep Dive into Functional Programming in Javascript


📈 31.72 Punkte
🔧 Programmierung

🔧 Deep Dive into Functional Programming in Javascript


📈 31.72 Punkte
🔧 Programmierung

🔧 Deep Dive into Data structures using Javascript - Graph


📈 31.72 Punkte
🔧 Programmierung

🔧 Unlocking JavaScript: A Deep Dive into Fundamentals.🚀🚀


📈 31.72 Punkte
🔧 Programmierung

🔧 A Deep Dive into the `array.map` Method - Mastering JavaScript


📈 31.72 Punkte
🔧 Programmierung

🔧 Mastering JavaScript: Deep Dive into Array Tooling.🚀🚀


📈 31.72 Punkte
🔧 Programmierung

matomo