.agents/skills/vercel-react-best-practices/rules/async-defer-await.md
Move await operations into the branches where they're actually used to avoid blocking code paths that don't need them.
Incorrect (blocks both branches):
async function handleRequest(userId: string, skipProcessing: boolean) {
const userData = await fetchUserData(userId)
if (skipProcessing) {
// Returns immediately but still waited for userData
return {skipped: true}
}
// Only this branch uses userData
return processUserData(userData)
}
Correct (only blocks when needed):
async function handleRequest(userId: string, skipProcessing: boolean) {
if (skipProcessing) {
// Returns immediately without waiting
return {skipped: true}
}
// Fetch only when needed
const userData = await fetchUserData(userId)
return processUserData(userData)
}
Another example (early return optimization):
// Incorrect: always fetches permissions
async function updateResource(resourceId: string, userId: string) {
const permissions = await fetchPermissions(userId)
const resource = await getResource(resourceId)
if (!resource) {
return {error: 'Not found'}
}
if (!permissions.canEdit) {
return {error: 'Forbidden'}
}
return await updateResourceData(resource, permissions)
}
// Correct: fetches only when needed
async function updateResource(resourceId: string, userId: string) {
const resource = await getResource(resourceId)
if (!resource) {
return {error: 'Not found'}
}
const permissions = await fetchPermissions(userId)
if (!permissions.canEdit) {
return {error: 'Forbidden'}
}
return await updateResourceData(resource, permissions)
}
This optimization is especially valuable when the skipped branch is frequently taken, or when the deferred operation is expensive.