cancel()
Cancel the futurable operation.
Syntax
typescript
futurable.cancel(): voidParameters
None.
Return Value
void - This method doesn't return anything.
Description
The cancel() method aborts the futurable operation. When called:
- The internal
AbortSignalis triggered - All registered
onCancelcallbacks are executed - Any ongoing async operations should be cleaned up
- The futurable is rejected with an
AbortError(if not already settled)
Calling cancel() on an already settled (fulfilled or rejected) futurable has no effect.
Examples
Basic Cancellation
typescript
import { Futurable } from '@ndriadev/futurable';
const futurable = new Futurable((resolve, reject, { signal }) => {
const timeout = setTimeout(() => resolve('Done'), 5000);
signal.addEventListener('abort', () => {
clearTimeout(timeout);
reject(new Error('Operation cancelled'));
});
});
// Cancel after 2 seconds
setTimeout(() => futurable.cancel(), 2000);
futurable
.then(result => console.log('Success:', result))
.catch(error => console.log('Error:', error.message)); // "Operation cancelled"Cancel Fetch Request
typescript
const request = Futurable.fetch('https://api.example.com/large-file');
// Start download
request
.then(response => response.blob())
.then(blob => console.log('Downloaded:', blob.size))
.catch(error => {
if (error.name === 'AbortError') {
console.log('Download cancelled');
}
});
// Cancel after 3 seconds
setTimeout(() => request.cancel(), 3000);Cancel in Promise Chain
typescript
const operation = Futurable
.fetch('/api/users')
.then(response => response.json())
.then(users => {
console.log('Processing users...');
return users.map(u => u.name);
});
// Cancelling works anywhere in the chain
operation.cancel();
// The fetch will be aborted, preventing .then callbacks from runningMultiple Operations
typescript
const operation1 = Futurable.fetch('/api/data1');
const operation2 = Futurable.fetch('/api/data2');
const operation3 = Futurable.fetch('/api/data3');
// Cancel all
operation1.cancel();
operation2.cancel();
operation3.cancel();Cancel with Futurable.all
typescript
const allOperations = Futurable.all([
Futurable.fetch('/api/users'),
Futurable.fetch('/api/posts'),
Futurable.fetch('/api/comments')
]);
// Cancelling the combined futurable cancels all sub-operations
allOperations.cancel();Cancel with Polling
typescript
const polling = Futurable.polling(
() => Futurable.fetch('/api/status').then(r => r.json()),
5000 // Poll every 5 seconds
);
// Stop polling after 30 seconds
setTimeout(() => polling.cancel(), 30000);Common Patterns
Cleanup Pattern
typescript
const futurable = new Futurable((resolve, reject, { signal }) => {
const resources = allocateResources();
signal.addEventListener('abort', () => {
// Clean up resources when cancelled
resources.cleanup();
});
// Async work
doWork(resources)
.then(resolve)
.catch(reject);
});
// Later
futurable.cancel(); // Resources are cleaned upUser Cancellation
typescript
// User can cancel long operation
function downloadFile(url, onProgress) {
const download = Futurable
.fetch(url)
.then(response => {
const reader = response.body.getReader();
// Process stream...
});
// Return cancel function
return {
promise: download,
cancel: () => download.cancel()
};
}
// Usage
const { promise, cancel } = downloadFile('https://example.com/file.zip');
// Show cancel button to user
document.getElementById('cancel-btn').onclick = cancel;Timeout Pattern
typescript
function withTimeout(futurable, timeoutMs) {
const timeout = setTimeout(() => {
futurable.cancel();
}, timeoutMs);
return futurable.finally(() => clearTimeout(timeout));
}
// Usage
const operation = Futurable.fetch('/api/slow-endpoint');
const withTimeout = withTimeout(operation, 5000);
withTimeout
.then(result => console.log('Success:', result))
.catch(error => {
if (error.name === 'AbortError') {
console.log('Operation timed out');
}
});React Cleanup
jsx
import { useEffect } from 'react';
import { Futurable } from '@ndriadev/futurable';
function Component() {
useEffect(() => {
const request = Futurable
.fetch('/api/data')
.then(r => r.json())
.then(setData);
// Cancel on unmount
return () => request.cancel();
}, []);
return <div>Component</div>;
}Notes
Idempotent Operation
Calling cancel() multiple times is safe and has no additional effect:
typescript
const futurable = Futurable.sleep(1000);
futurable.cancel(); // Cancels
futurable.cancel(); // No-op
futurable.cancel(); // No-opAlready Settled
Cancelling a settled futurable has no effect:
typescript
const futurable = Futurable.resolve('value');
futurable.cancel(); // No effect, already resolved
await futurable; // Still resolves to 'value'Synchronous
The cancel() method is synchronous - it returns immediately:
typescript
const futurable = Futurable.sleep(1000);
console.log('Before cancel');
futurable.cancel();
console.log('After cancel'); // Executes immediatelyError Type
When a futurable is cancelled, it's typically rejected with an error that has:
name: 'AbortError'(for fetch operations)- Or a custom error message
typescript
futurable
.catch(error => {
console.log(error.name); // 'AbortError' or similar
console.log(error.message); // Error message
});See Also
- onCancel() - Register cancellation callbacks
- Constructor - Creating cancellable operations
- Cancellation Guide - Learn about cancellation patterns
- Futurable.all() - Cancel multiple operations
- fetch() - Cancellable fetch requests
