Transitioning from Callbacks to Promises for Asynchronous JavaScript
Strategies for replacing callback-based asynchronous code with Promises to improve readability and maintainability in JavaScript.
0 likes
10 views
Rule Content
--- description: Enforce the use of Promises over callbacks for asynchronous operations in JavaScript to enhance code readability and maintainability. globs: ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] tags: [JavaScript, Promises, Asynchronous] priority: 2 version: 1.0.0 --- # Transitioning from Callbacks to Promises for Asynchronous JavaScript ## Context - **When to Apply**: In all JavaScript codebases where asynchronous operations are performed. - **Prerequisites**: Familiarity with JavaScript's asynchronous programming patterns, including callbacks and Promises. ## Requirements - **Use Promises Instead of Callbacks**: Replace traditional callback-based asynchronous code with Promises to improve readability and maintainability. - **Error Handling**: Implement `.catch()` for error handling in Promises to ensure errors are properly managed. - **Chaining**: Utilize `.then()` chaining for sequential asynchronous operations to avoid callback nesting (callback hell). - **Async/Await Syntax**: Prefer `async/await` syntax over `.then()` chaining for cleaner and more readable asynchronous code. ## Examples <example> **Good Example**: Using Promises with `fetch` API fetch('https://api.example.com/data') .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('There was a problem with the fetch operation:', error); }); In this example, Promises are used to handle asynchronous operations, providing clear error handling and avoiding nested callbacks. </example> <example> **Good Example**: Using `async/await` with `fetch` API async function fetchData() { try { const response = await fetch('https://api.example.com/data'); if (!response.ok) { throw new Error('Network response was not ok'); } const data = await response.json(); console.log(data); } catch (error) { console.error('There was a problem with the fetch operation:', error); } } fetchData(); This example demonstrates the use of `async/await` syntax, making the asynchronous code more readable and maintainable. </example> <example type="invalid"> **Bad Example**: Using Callbacks with `XMLHttpRequest` function fetchData(callback) { const xhr = new XMLHttpRequest(); xhr.open('GET', 'https://api.example.com/data', true); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { callback(null, JSON.parse(xhr.responseText)); } else { callback(new Error('Request failed')); } } }; xhr.send(); } fetchData(function (error, data) { if (error) { console.error('There was a problem with the request:', error); } else { console.log(data); } }); This example uses callbacks for handling asynchronous operations, which can lead to callback nesting and reduced readability. </example>