0
# Flow Control and Timing
1
2
Utilities for controlling promise execution timing, delays, timeouts, conditional processing, and managing asynchronous flow.
3
4
## Capabilities
5
6
### Delay Operations
7
8
Creates promises that resolve after a specified time delay.
9
10
```javascript { .api }
11
/**
12
* Returns promise that resolves after specified milliseconds
13
* @param object - Value to resolve with after delay
14
* @param timeout - Delay in milliseconds
15
* @returns Promise that resolves to object after timeout
16
*/
17
function Q.delay(object, timeout);
18
19
/**
20
* Delays fulfillment by specified milliseconds
21
* @param ms - Delay duration in milliseconds
22
* @returns Promise that resolves to same value after delay
23
*/
24
promise.delay(ms);
25
```
26
27
**Usage Examples:**
28
29
```javascript
30
const Q = require("q");
31
32
// Static delay with value
33
Q.delay("Hello after 1 second", 1000)
34
.then(message => console.log(message));
35
36
// Instance delay
37
Q.resolve("Immediate value")
38
.delay(500)
39
.then(value => console.log("Delayed:", value));
40
41
// Delay in promise chain
42
fetchUserData()
43
.then(user => {
44
console.log("Processing user:", user.name);
45
return user;
46
})
47
.delay(1000) // Wait 1 second before next step
48
.then(user => sendWelcomeEmail(user));
49
50
// Creating delays without values
51
Q.delay(2000).then(() => {
52
console.log("2 seconds have passed");
53
});
54
```
55
56
### Timeout Operations
57
58
Rejects promises if they don't resolve within a specified time limit.
59
60
```javascript { .api }
61
/**
62
* Rejects promise if not fulfilled before timeout
63
* @param object - Promise or value to timeout
64
* @param ms - Timeout duration in milliseconds
65
* @param message - Optional custom timeout message
66
* @returns Promise that rejects if timeout exceeded
67
*/
68
function Q.timeout(object, ms, message);
69
70
/**
71
* Rejects if not fulfilled within timeout
72
* @param ms - Timeout duration in milliseconds
73
* @param message - Optional custom timeout message
74
* @returns Promise that rejects on timeout
75
*/
76
promise.timeout(ms, message);
77
```
78
79
**Usage Examples:**
80
81
```javascript
82
const Q = require("q");
83
84
// Static timeout
85
Q.timeout(slowOperation(), 5000, "Operation took too long")
86
.then(result => console.log("Completed:", result))
87
.catch(error => console.error("Error:", error.message));
88
89
// Instance timeout
90
fetchDataFromAPI()
91
.timeout(3000, "API request timed out")
92
.then(data => processData(data))
93
.catch(error => {
94
if (error.message.includes("timed out")) {
95
return getDataFromCache();
96
}
97
throw error;
98
});
99
100
// Timeout with race pattern
101
function timeoutPromise(promise, ms) {
102
return Q.race([
103
promise,
104
Q.delay(ms).then(() => {
105
throw new Error(`Operation timed out after ${ms}ms`);
106
})
107
]);
108
}
109
```
110
111
### Conditional Processing
112
113
Handles conditional promise processing and value-based branching.
114
115
```javascript { .api }
116
/**
117
* Conditional promise handling with optional timing estimate
118
* @param value - Value or promise to process
119
* @param fulfilled - Callback for successful resolution
120
* @param rejected - Optional callback for rejection
121
* @param ms - Optional timing estimate
122
* @returns Promise for conditional result
123
*/
124
function Q.when(value, fulfilled, rejected, ms);
125
126
/**
127
* Resolves to value if both promises fulfill to same value
128
* @param x - First promise or value
129
* @param y - Second promise or value
130
* @returns Promise that resolves if both values are equal
131
*/
132
function Q.join(x, y);
133
```
134
135
**Usage Examples:**
136
137
```javascript
138
const Q = require("q");
139
140
// Conditional processing with Q.when
141
function processInput(input) {
142
return Q.when(input,
143
value => {
144
if (typeof value === "string") {
145
return value.toUpperCase();
146
}
147
return String(value);
148
},
149
error => {
150
console.error("Input processing failed:", error);
151
return "DEFAULT";
152
}
153
);
154
}
155
156
// Join operation for equality checking
157
const user1Promise = fetchUser(1);
158
const user2Promise = fetchUser(2);
159
160
Q.join(
161
user1Promise.then(u => u.department),
162
user2Promise.then(u => u.department)
163
).then(department => {
164
console.log("Both users are in department:", department);
165
}).catch(() => {
166
console.log("Users are in different departments");
167
});
168
169
// Complex conditional flow
170
function handleUserAction(userId, action) {
171
return Q.when(validateUser(userId),
172
user => {
173
if (user.permissions.includes(action)) {
174
return performAction(user, action);
175
} else {
176
throw new Error("Insufficient permissions");
177
}
178
},
179
error => {
180
console.error("User validation failed:", error);
181
return logUnauthorizedAttempt(userId, action);
182
}
183
);
184
}
185
```
186
187
### Finally Operations
188
189
Executes cleanup code regardless of promise resolution or rejection.
190
191
```javascript { .api }
192
/**
193
* Executes callback regardless of fulfillment or rejection
194
* @param callback - Function to execute for cleanup
195
* @param ms - Optional timing estimate
196
* @returns Promise that preserves original result
197
*/
198
promise.finally(callback, ms);
199
```
200
201
**Usage Examples:**
202
203
```javascript
204
const Q = require("q");
205
206
// Resource cleanup
207
function processFile(filename) {
208
let fileHandle;
209
210
return openFile(filename)
211
.then(handle => {
212
fileHandle = handle;
213
return processFileContents(handle);
214
})
215
.finally(() => {
216
if (fileHandle) {
217
closeFile(fileHandle);
218
console.log("File closed");
219
}
220
});
221
}
222
223
// Loading state management
224
function fetchUserData(userId) {
225
showLoadingSpinner();
226
227
return apiClient.getUser(userId)
228
.then(user => {
229
updateUserInterface(user);
230
return user;
231
})
232
.catch(error => {
233
showErrorMessage(error.message);
234
throw error;
235
})
236
.finally(() => {
237
hideLoadingSpinner();
238
});
239
}
240
241
// Database transaction cleanup
242
function updateUserRecord(userId, data) {
243
let transaction;
244
245
return database.beginTransaction()
246
.then(tx => {
247
transaction = tx;
248
return transaction.update("users", userId, data);
249
})
250
.then(result => {
251
return transaction.commit().then(() => result);
252
})
253
.catch(error => {
254
if (transaction) {
255
return transaction.rollback().then(() => {
256
throw error;
257
});
258
}
259
throw error;
260
})
261
.finally(() => {
262
console.log("Transaction completed");
263
});
264
}
265
```
266
267
### Value Transformation
268
269
Methods for transforming promise values regardless of original outcome.
270
271
```javascript { .api }
272
/**
273
* Resolves to specific value regardless of original result
274
* @param value - Value to resolve with
275
* @returns Promise that resolves to the specified value
276
*/
277
promise.thenResolve(value);
278
279
/**
280
* Rejects with specific error regardless of original result
281
* @param error - Error to reject with
282
* @returns Promise that rejects with the specified error
283
*/
284
promise.thenReject(error);
285
```
286
287
**Usage Examples:**
288
289
```javascript
290
const Q = require("q");
291
292
// Transform success to specific value
293
fetchUserPreferences()
294
.thenResolve("preferences loaded")
295
.then(message => console.log(message));
296
297
// Transform any outcome to error
298
riskyOperation()
299
.thenReject(new Error("Operation deprecated"))
300
.catch(error => console.error(error.message));
301
302
// Conditional transformation
303
function processWithFallback(data) {
304
return validateData(data)
305
.then(valid => valid ? data : null)
306
.catch(() => null)
307
.then(result => {
308
if (result === null) {
309
return Q.resolve().thenResolve("default data");
310
}
311
return result;
312
});
313
}
314
```