Delegate independent tasks to specialized agents working concurrently with isolated context.
Async Await Patterns
async-await-patterns
Use when writing JavaScript or TypeScript code with asynchronous operations
SKILL.md
Full skill instructions
<CRITICAL_INSTRUCTION> You MUST use async/await for ALL asynchronous operations instead of raw promises, callbacks, or blocking patterns. This is critical to application stability. This is NOT optional. This is NOT negotiable. </CRITICAL_INSTRUCTION>
Invariant Principles
- Explicit async boundary: Function containing await MUST be marked async. Compiler enforces; no exceptions.
- Await ALL promises: Every promise-returning call requires await. Missing await = bug (returns Promise, not value).
- Structured error handling: try-catch wraps async operations. Unhandled rejections crash applications.
- Pattern consistency: async/await XOR promise chains. Never mix in same function.
- Parallelism via combinators: Independent operations use Promise.all/allSettled. Sequential only when dependencies exist.
Required Reasoning
<analysis> Before writing ANY async code, verify step-by-step:- Is this operation asynchronous? (API calls, file I/O, timers, database queries)
- Did I mark the containing function as
async? - Did I use
awaitfor every promise-returning operation? - Did I add proper try-catch error handling?
- Did I avoid mixing async/await with
.then()/.catch()? - Can independent operations run in parallel with Promise.all?
Now write asynchronous code following this checklist. </analysis>
Core Pattern
async function operationName(): Promise<ReturnType> {
try {
const result = await asyncOperation();
return result;
} catch (error) {
// Handle or rethrow with context
throw error;
}
}
Forbidden Patterns: Quick Reference
| Anti-pattern | Fix |
|---|---|
.then()/.catch() chains | async/await with try-catch |
const x = asyncFn() (missing await) | const x = await asyncFn() |
function with await inside | async function |
| Await without try-catch | Wrap in try-catch |
| Mix async/await + .then() | Pure async/await |
| Callbacks when promises available | async/await |
| Sequential awaits for independent ops | Promise.all |
Forbidden Patterns: Detailed Examples
<FORBIDDEN pattern="1"> ### Raw Promise Chains Instead of Async/Await// 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;
}
}
</FORBIDDEN>
<FORBIDDEN pattern="2"> ### Forgetting await Keyword// 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;
}
</FORBIDDEN>
<FORBIDDEN pattern="3"> ### Missing async Keyword on Function// 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;
}
</FORBIDDEN>
<FORBIDDEN pattern="4"> ### Missing Error Handling// 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');
}
}
</FORBIDDEN>
<FORBIDDEN pattern="5"> ### Mixing Async/Await with Promise Chains// 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;
}
}
</FORBIDDEN>
Parallel vs Sequential
// PARALLEL: independent operations
const [a, b, c] = await Promise.all([fetchA(), fetchB(), fetchC()]);
// SEQUENTIAL: each depends on previous
const inventory = await checkInventory();
const payment = await processPayment(inventory);
const order = await createOrder(payment);
// FAULT-TOLERANT: continue despite failures
const results = await Promise.allSettled([op1(), op2(), op3()]);
// Each result: { status: 'fulfilled', value } or { status: 'rejected', reason }
Complete Real-World Example
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}`);
}
}
Demonstrates: async keyword, await on every async operation, comprehensive try-catch, proper error types, parallel operations with Promise.all, consistent async/await throughout.
Inputs
| Input | Required | Description |
|---|---|---|
| Code with async operations | Yes | JavaScript/TypeScript code needing async handling |
| Dependency graph | No | Which operations depend on others (determines parallel vs sequential) |
Outputs
| Output | Type | Description |
|---|---|---|
| Async code | Inline | Properly structured async/await code |
| Error handling strategy | Inline | try-catch blocks with typed error handling |
Self-Check
<reflection> 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 mixing async/await with promise 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?
- Does error handling preserve error context?
If NO to ANY item above: STOP. Rewrite using proper async/await before proceeding. </reflection>
<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>
More Other skills
brand-guidelines
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
theme-factory
Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.
internal-comms
A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).
Fundamental design principles for writing maintainable, testable Python code.
responsive-design
Modern responsive layouts using container queries, fluid typography, CSS Grid, and mobile-first strategies.
Generate Playwright tests from scenarios using interactive browser exploration and validation.
Automated website exploration and test case generation using Playwright.
Modern React state management with Redux Toolkit, Zustand, Jotai, and React Query for every state category.
gdpr-data-handling
GDPR-compliant data handling with consent management, data subject rights, and privacy controls.
Python error handling patterns including input validation, exception hierarchies, and partial failure handling. Use when implementing validation logic, designing exception strategies, handling batch processing failures, or building robust APIs.
refactor-plan
Detailed multi-file refactor planning with safety checks and rollback guidance.
