返回 AiToEarn
async-defer-await.md
1 ---
2 title: Defer Await Until Needed
3 impact: HIGH
4 impactDescription: avoids blocking unused code paths
5 tags: async, await, conditional, optimization
6 ---
7
8 ## Defer Await Until Needed
9
10 Move `await` operations into the branches where they're actually used to avoid blocking code paths that don't need them.
11
12 **Incorrect (blocks both branches):**
13
14 ```typescript
15 async function handleRequest(userId: string, skipProcessing: boolean) {
16 const userData = await fetchUserData(userId)
17
18 if (skipProcessing) {
19 // Returns immediately but still waited for userData
20 return { skipped: true }
21 }
22
23 // Only this branch uses userData
24 return processUserData(userData)
25 }
26 ```
27
28 **Correct (only blocks when needed):**
29
30 ```typescript
31 async function handleRequest(userId: string, skipProcessing: boolean) {
32 if (skipProcessing) {
33 // Returns immediately without waiting
34 return { skipped: true }
35 }
36
37 // Fetch only when needed
38 const userData = await fetchUserData(userId)
39 return processUserData(userData)
40 }
41 ```
42
43 **Another example (early return optimization):**
44
45 ```typescript
46 // Incorrect: always fetches permissions
47 async function updateResource(resourceId: string, userId: string) {
48 const permissions = await fetchPermissions(userId)
49 const resource = await getResource(resourceId)
50
51 if (!resource) {
52 return { error: 'Not found' }
53 }
54
55 if (!permissions.canEdit) {
56 return { error: 'Forbidden' }
57 }
58
59 return await updateResourceData(resource, permissions)
60 }
61
62 // Correct: fetches only when needed
63 async function updateResource(resourceId: string, userId: string) {
64 const resource = await getResource(resourceId)
65
66 if (!resource) {
67 return { error: 'Not found' }
68 }
69
70 const permissions = await fetchPermissions(userId)
71
72 if (!permissions.canEdit) {
73 return { error: 'Forbidden' }
74 }
75
76 return await updateResourceData(resource, permissions)
77 }
78 ```
79
80 This optimization is especially valuable when the skipped branch is frequently taken, or when the deferred operation is expensive.
81
82 For `await getFlag()` combined with a cheap synchronous guard (`flag && someCondition`), see [Check Cheap Conditions Before Async Flags](./async-cheap-condition-before-await.md).
83
83 lines MARKDOWN