JAVASCRIPT
Poll API for Asynchronous Job Status Updates
Implement an efficient API polling mechanism to track the status of long-running backend processes, providing real-time updates to the user without WebSockets.
async function pollJobStatus(jobId, checkUrl, interval = 2000, maxAttempts = 30) {
let attempts = 0;
return new Promise((resolve, reject) => {
const poll = async () => {
if (attempts >= maxAttempts) {
return reject(new Error(`Polling timed out after ${maxAttempts} attempts.`));
}
attempts++;
try {
const response = await fetch(`${checkUrl}/${jobId}`);
if (!response.ok) {
throw new Error(`Failed to fetch job status: ${response.statusText}`);
}
const data = await response.json();
if (data.status === 'completed') {
resolve(data);
} else if (data.status === 'failed') {
reject(new Error(`Job ${jobId} failed: ${data.errorMessage || 'Unknown error'}`));
} else {
// Job is still 'pending' or 'processing', poll again
setTimeout(poll, interval);
}
} catch (error) {
console.error(`Polling attempt ${attempts} failed:`, error);
// Optionally, implement retry logic here with backoff
setTimeout(poll, interval); // Retry on network error as well
}
};
poll(); // Start the first poll immediately
});
}
// Usage example:
// (async () => {
// try {
// // 1. Initiate an async job on your backend
// // const startJobResponse = await fetch('/api/start-async-job', { method: 'POST' });
// // const { jobId } = await startJobResponse.json();
// const fakeJobId = 'abc-123'; // Assume you got this from a previous API call
// console.log(`Starting to poll for job ${fakeJobId}...`);
// const result = await pollJobStatus(fakeJobId, '/api/job-status', 1500, 20);
// console.log('Job completed successfully:', result);
// // Update UI with result
// } catch (error) {
// console.error('Job polling failed:', error.message);
// // Show error to user
// }
// })();
// Example backend endpoint structure for '/api/job-status/:jobId'
// GET /api/job-status/abc-123
// Responds with:
// { "jobId": "abc-123", "status": "processing", "progress": 50 }
// OR
// { "jobId": "abc-123", "status": "completed", "result": { "output": "processed data" } }
// OR
// { "jobId": "abc-123", "status": "failed", "errorMessage": "Input invalid" }
How it works: This snippet illustrates how to implement client-side polling for asynchronous API jobs. After initiating a long-running process on the backend (which returns a `jobId`), the `pollJobStatus` function repeatedly makes requests to a status endpoint at a defined `interval`. It continues until the job status indicates `completed` or `failed`, or until a `maxAttempts` limit is reached, providing a way to update the user interface with the job's progress or final result.