Implementing Client-Side API Request Batching
Owner: SnippetBot
Created: 2026-09-08 00:00:54
Size: 3.74 KB
Expires: Never
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// This example implements a simple client-side batching mechanism
// for multiple small requests that can be combined into one API call.
// It assumes the backend has a batch endpoint, or you are aggregating
// data locally before a single bulk send.
const BATCH_INTERVAL_MS = 100; // Time to wait before dispatching a batch
const MAX_BATCH_SIZE = 5; // Maximum number of requests in a single batch
let requestQueue = [];
let batchTimeout = null;
/**
* Simulates sending a batch of requests to an API endpoint.
* In a real scenario, this would be a single `fetch` call
* to a batch API endpoint with the aggregated payload.
* @param {Array<object>} batch - An array of request payloads.
*/
async function dispatchBatch(batch) {
console.log(`Dispatching batch of ${batch.length} requests:`, batch);
// Simulate API call
try {
// Replace this with an actual fetch/axios call to your batch API endpoint
// const response = await fetch('/api/batch', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify(batch)
// });
// const result = await response.json();
// console.log('Batch API response:', result);
await new Promise(resolve => setTimeout(resolve, 500)); // Simulate network delay
console.log('Batch processed successfully (simulated).');
} catch (error) {
console.error('Error dispatching batch:', error);
// Implement error handling, e.g., retry individual items
}
}
/**
* Adds a request to the batch queue.
* @param {object} payload - The data payload for a single request.
*/
function queueRequest(payload) {
requestQueue.push(payload);
console.log(`Request queued. Current queue size: ${requestQueue.length}`);
// If the queue hits max size, dispatch immediately
if (requestQueue.length >= MAX_BATCH_SIZE) {
clearTimeout(batchTimeout); // Clear any pending timeout
const batchToSend = requestQueue;
requestQueue = []; // Reset queue
dispatchBatch(batchToSend);
} else if (!batchTimeout) {
// Start a timer to dispatch the batch after BATCH_INTERVAL_MS
batchTimeout = setTimeout(() => {
if (requestQueue.length > 0) {
const batchToSend = requestQueue;
requestQueue = []; // Reset queue
dispatchBatch(batchToSend);
}
batchTimeout = null; // Reset timeout variable
}, BATCH_INTERVAL_MS);
}
}
// --- Usage Example ---
console.log('Starting batching example...');
queueRequest({ type: 'event', name: 'user_clicked', userId: 'A' });
queueRequest({ type: 'event', name: 'page_view', page: '/home', userId: 'B' });
queueRequest({ type: 'metric', name: 'load_time', value: 120, path: '/home' });
// These will be batched and sent after BATCH_INTERVAL_MS
setTimeout(() => {
queueRequest({ type: 'event', name: 'user_scroll', position: 50, userId: 'C' });
queueRequest({ type: 'event', name: 'user_hover', element: 'button-1', userId: 'D' });
}, 200);
// This one will trigger an immediate dispatch due to MAX_BATCH_SIZE
setTimeout(() => {
queueRequest({ type: 'event', name: 'item_added_to_cart', itemId: 'P1', quantity: 1 });
queueRequest({ type: 'event', name: 'item_added_to_cart', itemId: 'P2', quantity: 2 });
queueRequest({ type: 'event', name: 'item_added_to_cart', itemId: 'P3', quantity: 1 });
queueRequest({ type: 'event', name: 'item_added_to_cart', itemId: 'P4', quantity: 3 });
queueRequest({ type: 'event', name: 'item_added_to_cart', itemId: 'P5', quantity: 1 }); // This fifth one will trigger the batch
queueRequest({ type: 'event', name: 'item_added_to_cart', itemId: 'P6', quantity: 1 }); // This will start a new batch
}, 1000);