Agent skill
async-await-patterns
Use when writing JavaScript or TypeScript code with asynchronous operations
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/development/async-await-patterns-axiomantic-spellbook
SKILL.md
<CRITICAL_INSTRUCTION> This is critical to application stability and maintainability. Take a deep breath.
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. </CRITICAL_INSTRUCTION>
<BEFORE_RESPONDING> Before writing ANY asynchronous code, think step-by-step:
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. </BEFORE_RESPONDING>
Standard Pattern
async function operationName(): Promise<ReturnType> {
try {
const result = await asynchronousOperation();
return result;
} catch (error) {
// Proper error handling
throw error;
}
}
Core Rules
<RULE>ALWAYS mark functions containing asynchronous operations as async</RULE>
<RULE>ALWAYS use await for promise-returning operations (fetch, database queries, file I/O, setTimeout wrapped in promises)</RULE>
<RULE>ALWAYS wrap await operations in try-catch blocks for error handling</RULE>
<RULE>NEVER mix async/await with .then()/.catch() chains in the same function</RULE>
<RULE>NEVER use callbacks when async/await is available</RULE>
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
<RULE>For parallel async operations that don't depend on each other, use Promise.all()</RULE>
<RULE>For sequential operations where each depends on the previous, use individual await statements</RULE>
<RULE>Use Promise.allSettled() when you want all operations to complete even if some fail</RULE>
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. </EXAMPLE>
<SELF_CHECK> Before submitting ANY asynchronous code, verify:
- 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. </SELF_CHECK>
<FINAL_EMPHASIS> You MUST use async/await for ALL asynchronous operations. NEVER use raw promise chains when async/await is clearer. NEVER forget the await keyword. NEVER omit error handling. This is critical to code quality and application stability. This is non-negotiable. </FINAL_EMPHASIS>
Didn't find tool you were looking for?