Implementing Consistent Use of Promises in JavaScript
Define guidelines for using promises effectively to manage asynchronous operations while maintaining code clarity.
0 likes
26 views
Rule Content
--- name: consistent-use-of-promises description: Enforce consistent and effective use of Promises in JavaScript to manage asynchronous operations and maintain code clarity. category: JavaScript Cursor Rules version: 1.0 globs: - "**/*.js" - "**/*.jsx" - "**/*.ts" - "**/*.tsx" triggers: - file_open - file_save - file_change --- # Consistent Use of Promises in JavaScript ## Objective Ensure that asynchronous operations in JavaScript are handled consistently using Promises, enhancing code readability and maintainability. ## Guidelines 1. **Prefer Promises Over Callbacks** - **Rationale:** Promises provide a cleaner and more manageable approach to handling asynchronous operations compared to traditional callbacks, reducing callback nesting and improving readability. - **Example:** ```javascript // Bad: Using callbacks function fetchData(callback) { fetch('https://api.example.com/data', function(err, data) { if (err) { callback(err); } else { callback(null, data); } }); } // Good: Using Promises function fetchData() { return fetch('https://api.example.com/data') .then(response => response.json()); } ``` 2. **Utilize Async/Await Syntax** - **Rationale:** The `async/await` syntax, introduced in ES2017, allows for writing asynchronous code that is more readable and resembles synchronous code, making it easier to understand and maintain. - **Example:** ```javascript // Bad: Using .then() chaining fetchData() .then(data => { processData(data); }) .catch(error => { handleError(error); }); // Good: Using async/await async function handleData() { try { const data = await fetchData(); processData(data); } catch (error) { handleError(error); } } ``` 3. **Handle Errors Appropriately** - **Rationale:** Proper error handling in asynchronous operations prevents unhandled promise rejections and ensures that errors are managed gracefully. - **Example:** ```javascript // Bad: Missing error handling async function fetchData() { const response = await fetch('https://api.example.com/data'); const data = await response.json(); return data; } // Good: Including error handling async function fetchData() { try { const response = await fetch('https://api.example.com/data'); const data = await response.json(); return data; } catch (error) { console.error('Error fetching data:', error); throw error; } } ``` 4. **Avoid Mixing Promises with Callbacks** - **Rationale:** Mixing Promises with callbacks can lead to confusion and potential errors. Consistency in using Promises throughout the codebase ensures clarity and predictability. - **Example:** ```javascript // Bad: Mixing Promises with callbacks function fetchData(callback) { fetch('https://api.example.com/data') .then(response => response.json()) .then(data => callback(null, data)) .catch(error => callback(error)); } // Good: Using Promises consistently function fetchData() { return fetch('https://api.example.com/data') .then(response => response.json()); } ``` 5. **Use `Promise.all` for Concurrent Operations** - **Rationale:** When multiple asynchronous operations can be performed concurrently, `Promise.all` allows them to run in parallel, improving performance. - **Example:** ```javascript // Bad: Sequential execution async function fetchMultipleData() { const data1 = await fetchData1(); const data2 = await fetchData2(); return [data1, data2]; } // Good: Concurrent execution async function fetchMultipleData() { const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]); return [data1, data2]; } ``` 6. **Use `Promise.any` for First-Resolved Operations** - **Rationale:** When the first successful result from multiple asynchronous operations is sufficient, `Promise.any` returns the first resolved promise, ignoring the rest. - **Example:** ```javascript // Using Promise.any async function fetchFirstAvailableData() { try { const data = await Promise.any([fetchData1(), fetchData2(), fetchData3()]); return data; } catch (error) { console.error('All promises rejected:', error); throw error; } } ``` ## Implementation - **Enforcement:** Integrate this rule into the project's linting configuration to automatically detect and enforce consistent use of Promises. - **Education:** Provide training and resources to developers on the benefits and proper usage of Promises and async/await syntax. - **Code Reviews:** During code reviews, ensure that asynchronous operations adhere to these guidelines, providing feedback and corrections as necessary. ## References - [JavaScript Promises: An Introduction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises) - [Async/Await](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Promises#async_and_await) - [Promise.any()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any)