- Spec files
npm-axios
Describes: pkg:npm/axios@1.11.x
- Description
- Promise based HTTP client for the browser and node.js
- Author
- tessl
- Last updated
cancellation.md docs/
1# Request Cancellation23Cancel HTTP requests to prevent unnecessary network usage, handle component cleanup, and improve application performance. Axios supports both legacy CancelToken and modern AbortSignal approaches.45## Capabilities67### CancelToken (Legacy)89Token-based cancellation system for backward compatibility.1011```javascript { .api }12/**13* CancelToken constructor14* @param executor - Function that receives cancel function15*/16class CancelToken {17constructor(executor: (cancel: Canceler) => void);1819/** Promise that resolves when token is canceled */20promise: Promise<Cancel>;21/** Cancellation reason if canceled */22reason?: Cancel;2324/** Throw error if request was canceled */25throwIfRequested(): void;26}2728/**29* Create cancel token source30* @returns Object with token and cancel function31*/32CancelToken.source(): CancelTokenSource;3334interface CancelTokenSource {35/** Token to use in request config */36token: CancelToken;37/** Function to cancel the request */38cancel: Canceler;39}4041interface Canceler {42(message?: string, config?: AxiosRequestConfig, request?: any): void;43}44```4546**Usage Examples:**4748```javascript49import axios from "axios";5051// Using CancelToken.source()52const source = axios.CancelToken.source();5354axios.get("https://api.example.com/data", {55cancelToken: source.token56}).catch((error) => {57if (axios.isCancel(error)) {58console.log("Request canceled:", error.message);59} else {60console.error("Request failed:", error);61}62});6364// Cancel the request65source.cancel("Operation canceled by user");6667// Using CancelToken constructor68let cancel;69const cancelToken = new axios.CancelToken((c) => {70cancel = c;71});7273axios.post("https://api.example.com/upload", formData, {74cancelToken: cancelToken,75onUploadProgress: (progressEvent) => {76const progress = (progressEvent.loaded / progressEvent.total) * 100;77console.log(`Upload progress: ${progress}%`);78}79});8081// Cancel upload82cancel("Upload canceled");83```8485### AbortSignal (Modern)8687Modern browser-standard cancellation using AbortController.8889```javascript { .api }90// Uses standard AbortController API91interface AbortController {92/** Signal to pass to axios config */93signal: AbortSignal;94/** Cancel all requests using this signal */95abort(): void;96}9798interface AbortSignal {99/** Whether the signal has been aborted */100readonly aborted: boolean;101/** Event handler for abort events */102onabort?: ((this: AbortSignal, ev: Event) => any) | null;103/** Add event listener for abort */104addEventListener(type: "abort", listener: (ev: Event) => void): void;105/** Remove event listener for abort */106removeEventListener(type: "abort", listener: (ev: Event) => void): void;107}108```109110**Usage Examples:**111112```javascript113// Basic AbortController usage114const controller = new AbortController();115116axios.get("https://api.example.com/users", {117signal: controller.signal118}).catch((error) => {119if (error.name === "AbortError" || axios.isCancel(error)) {120console.log("Request aborted");121} else {122console.error("Request failed:", error);123}124});125126// Abort the request127controller.abort();128129// Timeout with AbortController130function fetchWithTimeout(url, timeout = 5000) {131const controller = new AbortController();132133const timeoutId = setTimeout(() => {134controller.abort();135}, timeout);136137return axios.get(url, { signal: controller.signal })138.finally(() => clearTimeout(timeoutId));139}140141// Usage142fetchWithTimeout("https://api.example.com/slow-endpoint", 3000)143.then(response => console.log(response.data))144.catch(error => {145if (error.name === "AbortError") {146console.log("Request timed out");147}148});149```150151### Cancellation Detection152153Check if an error was caused by request cancellation.154155```javascript { .api }156/**157* Check if error is due to request cancellation158* @param value - Error or any value to check159* @returns True if value is a cancellation error160*/161axios.isCancel(value: any): boolean;162163/**164* Check if error is an AxiosError (includes cancellation errors)165* @param payload - Error or any value to check166* @returns True if payload is an AxiosError167*/168axios.isAxiosError(payload: any): boolean;169```170171**Usage Examples:**172173```javascript174try {175const response = await axios.get(url, { cancelToken: source.token });176console.log(response.data);177} catch (error) {178if (axios.isCancel(error)) {179console.log("Request was canceled:", error.message);180} else if (axios.isAxiosError(error)) {181console.log("Axios error:", error.message);182console.log("Status:", error.response?.status);183} else {184console.log("Unknown error:", error);185}186}187188// With AbortController189try {190const response = await axios.get(url, { signal: controller.signal });191console.log(response.data);192} catch (error) {193if (error.name === "AbortError" || axios.isCancel(error)) {194console.log("Request was aborted");195} else {196console.log("Other error:", error.message);197}198}199```200201### Cancel and CanceledError202203Objects representing cancellation reasons and errors.204205```javascript { .api }206/**207* Cancellation reason object208*/209interface Cancel {210/** Cancellation message */211message: string | undefined;212}213214/**215* Error thrown when request is canceled216*/217class CanceledError extends AxiosError {218constructor(message?: string, config?: InternalAxiosRequestConfig, request?: any);219}220221// Legacy alias for backward compatibility222const Cancel = CanceledError;223```224225### React Component Integration226227Common patterns for canceling requests in React components.228229**Usage Examples:**230231```javascript232import { useEffect, useState } from "react";233import axios from "axios";234235// Hook for cancelable requests236function useCancelableRequest() {237useEffect(() => {238const controller = new AbortController();239240return () => {241controller.abort(); // Cleanup on unmount242};243}, []);244}245246// Component with request cancellation247function UserProfile({ userId }) {248const [user, setUser] = useState(null);249const [loading, setLoading] = useState(false);250251useEffect(() => {252const controller = new AbortController();253254async function fetchUser() {255setLoading(true);256try {257const response = await axios.get(`/api/users/${userId}`, {258signal: controller.signal259});260setUser(response.data);261} catch (error) {262if (!axios.isCancel(error)) {263console.error("Failed to fetch user:", error);264}265} finally {266setLoading(false);267}268}269270fetchUser();271272return () => {273controller.abort(); // Cancel on cleanup274};275}, [userId]);276277return loading ? <div>Loading...</div> : <div>{user?.name}</div>;278}279280// Custom hook for API calls281function useAPI(url) {282const [data, setData] = useState(null);283const [loading, setLoading] = useState(false);284const [error, setError] = useState(null);285286useEffect(() => {287const controller = new AbortController();288289async function fetchData() {290setLoading(true);291setError(null);292293try {294const response = await axios.get(url, {295signal: controller.signal296});297setData(response.data);298} catch (err) {299if (!axios.isCancel(err)) {300setError(err);301}302} finally {303setLoading(false);304}305}306307if (url) {308fetchData();309}310311return () => {312controller.abort();313};314}, [url]);315316return { data, loading, error };317}318```319320### Multiple Request Cancellation321322Cancel multiple requests with a single signal or token.323324**Usage Examples:**325326```javascript327// Cancel multiple requests with one controller328const controller = new AbortController();329330const requests = [331axios.get("/api/users", { signal: controller.signal }),332axios.get("/api/posts", { signal: controller.signal }),333axios.get("/api/comments", { signal: controller.signal })334];335336Promise.allSettled(requests)337.then(results => {338results.forEach((result, index) => {339if (result.status === "fulfilled") {340console.log(`Request ${index} succeeded:`, result.value.data);341} else if (!axios.isCancel(result.reason)) {342console.log(`Request ${index} failed:`, result.reason.message);343}344});345});346347// Cancel all requests348controller.abort();349350// With CancelToken351const source = axios.CancelToken.source();352353const cancelableRequests = [354axios.get("/api/data1", { cancelToken: source.token }),355axios.get("/api/data2", { cancelToken: source.token }),356axios.get("/api/data3", { cancelToken: source.token })357];358359// Cancel all360source.cancel("Batch operation canceled");361```362363### Request Timeout vs Cancellation364365Distinguish between timeouts and manual cancellation.366367**Usage Examples:**368369```javascript370// Combine timeout with manual cancellation371function fetchWithTimeoutAndCancel(url, timeout = 5000) {372const controller = new AbortController();373let timeoutId;374375const request = axios.get(url, {376signal: controller.signal,377timeout: timeout // Axios timeout378});379380// Manual timeout using AbortController381const timeoutPromise = new Promise((_, reject) => {382timeoutId = setTimeout(() => {383controller.abort();384reject(new Error("Request timed out"));385}, timeout);386});387388return Promise.race([request, timeoutPromise])389.finally(() => clearTimeout(timeoutId));390}391392// Error handling for different cancellation types393try {394const response = await axios.get(url, {395signal: controller.signal,396timeout: 5000397});398} catch (error) {399if (axios.isCancel(error)) {400console.log("Request was manually canceled");401} else if (error.code === "ECONNABORTED") {402console.log("Request timed out");403} else {404console.log("Other error:", error.message);405}406}407```