| name | async-await-patterns |
| description | Use when writing JavaScript or TypeScript code with asynchronous operations |
You MUST use async/await for ALL asynchronous operations instead of raw promises, callbacks, or blocking patterns. This is very important to my career.
This is NOT optional. This is NOT negotiable. You'd better be sure.
Step 1: Is this operation asynchronous? (API calls, file I/O, timers, database queries)
Step 2: Did I mark the containing function as async?
Step 3: Did I use await for every promise-returning operation?
Step 4: Did I add proper try-catch error handling?
Step 5: Did I avoid mixing async/await with .then()/.catch()?
Now write asynchronous code following this checklist.
Standard Pattern
async function operationName(): Promise<ReturnType> {
try {
const result = await asynchronousOperation();
return result;
} catch (error) {
// Proper error handling
throw error;
}
}
Core Rules
asyncawait for promise-returning operations (fetch, database queries, file I/O, setTimeout wrapped in promises)
Forbidden Patterns
// BAD - Using .then()/.catch() chains
function fetchData() {
return fetch('/api/data')
.then(response => response.json())
.then(data => processData(data))
.catch(error => handleError(error));
}
// CORRECT - Using async/await
async function fetchData() {
try {
const response = await fetch('/api/data');
const data = await response.json();
return processData(data);
} catch (error) {
handleError(error);
throw error;
}
}
// BAD - Missing await (returns Promise instead of value)
async function getData() {
const data = fetchFromDatabase(); // Forgot await!
return data.id; // Error: data is a Promise
}
// CORRECT - Using await
async function getData() {
const data = await fetchFromDatabase();
return data.id;
}
// BAD - Using await without async
function loadUser() {
const user = await database.getUser(); // SyntaxError!
return user;
}
// CORRECT - Mark function as async
async function loadUser() {
const user = await database.getUser();
return user;
}
// BAD - No try-catch for async operations
async function saveData(data) {
const result = await database.save(data);
return result; // Unhandled promise rejection if save fails!
}
// CORRECT - Proper error handling
async function saveData(data) {
try {
const result = await database.save(data);
return result;
} catch (error) {
console.error('Save failed:', error);
throw new Error('Failed to save data');
}
}
// BAD - Inconsistent pattern mixing
async function processUser() {
const user = await getUser();
return updateUser(user)
.then(result => result.data)
.catch(error => console.error(error));
}
// CORRECT - Consistent async/await
async function processUser() {
try {
const user = await getUser();
const result = await updateUser(user);
return result.data;
} catch (error) {
console.error(error);
throw error;
}
}
Advanced Patterns
Promise.all()Promise.allSettled() when you want all operations to complete even if some fail
Parallel Operations
async function loadDashboard() {
const [user, stats, notifications] = await Promise.all([
fetchUser(),
fetchStats(),
fetchNotifications()
]);
return { user, stats, notifications };
}
Sequential Operations
async function checkout() {
const inventory = await checkInventory();
const payment = await processPayment(inventory);
const order = await createOrder(payment);
return order;
}
When Some Operations May Fail
const results = await Promise.allSettled([op1(), op2(), op3()]);
// Each result has { status: 'fulfilled', value } or { status: 'rejected', reason }
async function updateUserProfile(userId: string, updates: ProfileUpdates): Promise<User> {
try {
const user = await database.users.findById(userId);
if (!user) {
throw new Error(`User ${userId} not found`);
}
const validatedUpdates = await validateProfileData(updates);
const updatedUser = await database.users.update(userId, validatedUpdates);
// Parallel operations for notifications
await Promise.all([
notificationService.send(userId, 'Profile updated'),
auditLog.record('profile_update', { userId, updates: validatedUpdates })
]);
return updatedUser;
} catch (error) {
if (error instanceof ValidationError) {
throw new BadRequestError('Invalid profile data', error);
}
if (error instanceof DatabaseError) {
throw new ServiceError('Database operation failed', error);
}
throw new Error(`Failed to update profile: ${error.message}`);
}
}
This demonstrates: async keyword, await on every async operation, comprehensive try-catch, proper error types, parallel operations with Promise.all, consistent async/await throughout.
- Did I mark the function as
async? - Did I use
awaitfor EVERY promise-returning operation? - Did I wrap await operations in try-catch blocks?
- Did I avoid using .then()/.catch() chains?
- Did I avoid using callbacks when async/await is available?
- Did I consider whether operations can run in parallel with Promise.all()?
- Did I provide meaningful error messages in catch blocks?
If NO to ANY item above, DELETE your code and rewrite using proper async/await.