0
# Advanced Operations
1
2
Advanced features including low-level dispatch operations, pass-by-copy semantics, timing estimates, and specialized promise operations.
3
4
## Capabilities
5
6
### Low-Level Dispatch Operations
7
8
Generic operation dispatch system for advanced promise manipulation.
9
10
```javascript { .api }
11
/**
12
* Generic operation dispatch on fulfilled value
13
* @param op - Operation name to dispatch
14
* @param args - Arguments for the operation
15
* @returns Promise for operation result
16
*/
17
promise.dispatch(op, args);
18
19
/**
20
* Low-level dispatch without promise wrapping
21
* @param resolve - Resolver function for the result
22
* @param op - Operation name to dispatch
23
* @param args - Arguments for the operation
24
* @returns void (calls resolve with result)
25
*/
26
promise.rawDispatch(resolve, op, args);
27
28
/**
29
* Generic operation dispatch on values (deprecated)
30
* @param value - Value to operate on
31
* @param op - Operation name
32
* @param operands - Operation arguments
33
* @returns Promise for operation result
34
*/
35
function Q.dispatch(value, op, operands);
36
```
37
38
**Usage Examples:**
39
40
```javascript
41
const Q = require("q");
42
43
// Custom dispatch operations
44
const objectPromise = Q.resolve({
45
values: [1, 2, 3, 4, 5],
46
transform: function(fn) { return this.values.map(fn); },
47
sum: function() { return this.values.reduce((a, b) => a + b, 0); }
48
});
49
50
// Dispatch custom operations
51
objectPromise.dispatch("transform", [x => x * 2])
52
.then(doubled => console.log("Doubled:", doubled)); // [2, 4, 6, 8, 10]
53
54
objectPromise.dispatch("sum", [])
55
.then(sum => console.log("Sum:", sum)); // 15
56
57
// Raw dispatch for performance-critical operations
58
function performRawOperation(promise, operation, args) {
59
return new Q.Promise((resolve, reject) => {
60
promise.rawDispatch((result) => {
61
try {
62
const operationResult = result[operation].apply(result, args);
63
resolve(operationResult);
64
} catch (error) {
65
reject(error);
66
}
67
}, operation, args);
68
});
69
}
70
71
// Using Q.dispatch (deprecated but still functional)
72
Q.dispatch({ name: "John" }, "get", ["name"])
73
.then(name => console.log("Name:", name));
74
75
// Advanced dispatch patterns
76
class PromiseDispatcher {
77
constructor(promise) {
78
this.promise = promise;
79
}
80
81
dispatchOperation(op, ...args) {
82
return this.promise.dispatch(op, args);
83
}
84
85
dispatchMultiple(operations) {
86
const dispatches = operations.map(({ op, args }) =>
87
this.promise.dispatch(op, args)
88
);
89
return Q.all(dispatches);
90
}
91
}
92
93
// Usage
94
const dispatcher = new PromiseDispatcher(objectPromise);
95
dispatcher.dispatchMultiple([
96
{ op: "sum", args: [] },
97
{ op: "transform", args: [x => x + 1] }
98
]).then(results => {
99
console.log("Dispatch results:", results);
100
});
101
```
102
103
### Pass-by-Copy Semantics
104
105
System for marking values and promises for pass-by-copy serialization behavior.
106
107
```javascript { .api }
108
/**
109
* Marks value for pass-by-copy semantics
110
* @param value - Value to mark for pass-by-copy
111
* @returns Value marked for pass-by-copy
112
*/
113
function Q.passByCopy(value);
114
// Alias: Q.push(value)
115
116
/**
117
* Checks if value is marked for pass-by-copy
118
* @param value - Value to check
119
* @returns True if value is marked for pass-by-copy
120
*/
121
function Q.isPortable(value);
122
123
/**
124
* Marks promise for pass-by-copy semantics
125
* @returns Promise marked for pass-by-copy
126
*/
127
promise.pass();
128
129
/**
130
* Checks if promise is marked for pass-by-copy
131
* @returns True if promise is marked for pass-by-copy
132
*/
133
promise.toBePassed();
134
135
/**
136
* Creates pass-by-copy snapshot of fulfilled object
137
* @returns Promise for serializable snapshot
138
*/
139
promise.pull();
140
```
141
142
**Usage Examples:**
143
144
```javascript
145
const Q = require("q");
146
147
// Mark values for pass-by-copy
148
const portableData = Q.passByCopy({
149
name: "John",
150
age: 30,
151
preferences: { theme: "dark" }
152
});
153
154
console.log(Q.isPortable(portableData)); // true
155
156
// Mark promises for pass-by-copy
157
const userPromise = fetchUser(123).pass();
158
159
console.log(userPromise.toBePassed()); // true
160
161
// Create serializable snapshots
162
const complexObjectPromise = Q.resolve({
163
id: 1,
164
data: new Map([["key1", "value1"], ["key2", "value2"]]),
165
timestamp: new Date(),
166
process: () => "cannot be serialized"
167
});
168
169
complexObjectPromise.pull()
170
.then(snapshot => {
171
console.log("Serializable snapshot:", snapshot);
172
// Contains only serializable properties
173
});
174
175
// Distributed computing example
176
function createDistributableTask(data) {
177
const portableData = Q.passByCopy(data);
178
179
return Q.resolve(portableData)
180
.pass() // Mark promise as portable
181
.then(data => {
182
// This promise can be serialized and sent to remote workers
183
return processOnRemoteWorker(data);
184
});
185
}
186
187
// Serialization utility
188
function serializePromiseChain(promise) {
189
if (promise.toBePassed()) {
190
return promise.pull().then(data => ({
191
type: "serialized_promise",
192
data: JSON.stringify(data),
193
portable: true
194
}));
195
} else {
196
throw new Error("Promise is not marked for serialization");
197
}
198
}
199
200
// Remote execution pattern
201
function executeRemoteley(localPromise) {
202
return localPromise
203
.pass()
204
.pull()
205
.then(serializableData => {
206
return sendToRemoteWorker(serializableData);
207
})
208
.then(remoteResult => {
209
return Q.passByCopy(remoteResult);
210
});
211
}
212
```
213
214
### Timing Estimates
215
216
System for tracking and observing promise completion time estimates.
217
218
```javascript { .api }
219
/**
220
* Observes changes to completion time estimates
221
* @param emit - Callback for estimate changes
222
* @returns Promise with estimate observation
223
*/
224
promise.observeEstimate(emit);
225
226
/**
227
* Gets current completion time estimate
228
* @returns Current estimate in milliseconds
229
*/
230
promise.getEstimate();
231
232
/**
233
* Sets completion time estimate on deferred
234
* @param estimate - Estimate in milliseconds
235
* @returns void
236
*/
237
deferred.setEstimate(estimate);
238
```
239
240
**Usage Examples:**
241
242
```javascript
243
const Q = require("q");
244
245
// Set estimates on deferred objects
246
const deferred = Q.defer();
247
deferred.setEstimate(5000); // Estimate 5 seconds
248
249
// Monitor estimate changes
250
deferred.promise.observeEstimate((estimate) => {
251
console.log(`Estimated completion in: ${estimate}ms`);
252
});
253
254
// Simulate work with estimate updates
255
setTimeout(() => {
256
deferred.setEstimate(3000); // Update to 3 seconds
257
}, 1000);
258
259
setTimeout(() => {
260
deferred.setEstimate(1000); // Update to 1 second
261
}, 2000);
262
263
setTimeout(() => {
264
deferred.resolve("Task completed");
265
}, 3000);
266
267
// Get current estimates
268
console.log("Initial estimate:", deferred.promise.getEstimate());
269
270
// Progress tracking utility
271
class ProgressTracker {
272
constructor(promise, name) {
273
this.promise = promise;
274
this.name = name;
275
this.startTime = Date.now();
276
277
this.setupEstimateObserver();
278
}
279
280
setupEstimateObserver() {
281
this.promise.observeEstimate((estimate) => {
282
const elapsed = Date.now() - this.startTime;
283
const remaining = Math.max(0, estimate - elapsed);
284
285
console.log(`${this.name}: ${remaining}ms remaining (${elapsed}ms elapsed)`);
286
287
if (remaining > 0) {
288
const percentage = (elapsed / estimate) * 100;
289
this.updateProgressBar(Math.min(100, percentage));
290
}
291
});
292
}
293
294
updateProgressBar(percentage) {
295
const bar = "█".repeat(Math.floor(percentage / 5)) +
296
"░".repeat(20 - Math.floor(percentage / 5));
297
console.log(`${this.name}: [${bar}] ${percentage.toFixed(1)}%`);
298
}
299
}
300
301
// Usage
302
function longRunningTask() {
303
const deferred = Q.defer();
304
deferred.setEstimate(10000); // 10 seconds
305
306
let progress = 0;
307
const timer = setInterval(() => {
308
progress += 1000;
309
deferred.setEstimate(10000 - progress);
310
311
if (progress >= 10000) {
312
clearInterval(timer);
313
deferred.resolve("Task completed");
314
}
315
}, 1000);
316
317
return deferred.promise;
318
}
319
320
const tracker = new ProgressTracker(longRunningTask(), "Data Processing");
321
```
322
323
### Iterator Support
324
325
Support for creating iterators from promised iterable values.
326
327
```javascript { .api }
328
/**
329
* Creates iterator for fulfilled iterable value
330
* @returns Promise for iterator object
331
*/
332
promise.iterate();
333
```
334
335
**Usage Examples:**
336
337
```javascript
338
const Q = require("q");
339
340
// Create iterator from promised array
341
const arrayPromise = Q.resolve([1, 2, 3, 4, 5]);
342
343
arrayPromise.iterate()
344
.then(iterator => {
345
console.log(iterator.next()); // { value: 1, done: false }
346
console.log(iterator.next()); // { value: 2, done: false }
347
console.log(iterator.next()); // { value: 3, done: false }
348
});
349
350
// Async iteration utility
351
function asyncIterate(iterablePromise, processor) {
352
return iterablePromise.iterate().then(iterator => {
353
const results = [];
354
355
function processNext() {
356
const { value, done } = iterator.next();
357
358
if (done) {
359
return results;
360
}
361
362
return Q.resolve(processor(value))
363
.then(processedValue => {
364
results.push(processedValue);
365
return processNext();
366
});
367
}
368
369
return processNext();
370
});
371
}
372
373
// Usage
374
const numbersPromise = Q.resolve([1, 2, 3, 4, 5]);
375
376
asyncIterate(numbersPromise, num => Q.delay(num * 2, 100))
377
.then(results => console.log("Processed results:", results));
378
379
// Stream processing with iterators
380
function streamProcess(dataPromise, batchSize = 3) {
381
return dataPromise.iterate().then(iterator => {
382
const batches = [];
383
let currentBatch = [];
384
385
function processBatch() {
386
const { value, done } = iterator.next();
387
388
if (done) {
389
if (currentBatch.length > 0) {
390
batches.push(currentBatch);
391
}
392
return batches;
393
}
394
395
currentBatch.push(value);
396
397
if (currentBatch.length >= batchSize) {
398
batches.push(currentBatch);
399
currentBatch = [];
400
}
401
402
return processBatch();
403
}
404
405
return processBatch();
406
});
407
}
408
409
// Usage
410
const largeDatasetPromise = Q.resolve(Array.from({ length: 10 }, (_, i) => i + 1));
411
412
streamProcess(largeDatasetPromise, 3)
413
.then(batches => {
414
console.log("Processed in batches:", batches);
415
// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
416
});
417
```