Axios如何取消請求,其原理是什么?
axios 可以通過創(chuàng)建一個(gè) CancelToken 來取消一個(gè)請求,基本原理是:
- 創(chuàng)建一個(gè) CancelToken 的實(shí)例,它有一個(gè) executor 函數(shù),可以通過調(diào)用 executor 參數(shù)中的 cancel 函數(shù)來取消請求。
- 在 axios 請求配置中指定 cancelToken 屬性,將 CancelToken 實(shí)例傳遞進(jìn)去。
- 當(dāng)我們需要取消請求時(shí),調(diào)用 CancelToken 實(shí)例的 cancel() 方法即可取消對應(yīng)的請求。
- axios 檢測到配置的 cancelToken 被取消,就會取消掉這個(gè)請求,并在錯(cuò)誤回調(diào)中返回一個(gè) Cancel 錯(cuò)誤。axios 內(nèi)部會監(jiān)聽 cancelToken 實(shí)例的 cancel 信號,一旦觸發(fā)就會跳出隊(duì)列,取消對應(yīng)請求的執(zhí)行。示例代碼:
js
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user', {
cancelToken: source.token
}).catch(function(thrown) {
if(axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 處理錯(cuò)誤
}
});
// 取消請求
source.cancel('Operation canceled by the user.');
vue、React項(xiàng)目中如何取消
在基于 React 或 Vue 的應(yīng)用中,可以通過封裝 Axios 并結(jié)合組件的狀態(tài)管理來實(shí)現(xiàn)取消請求的功能。下面分別介紹在 React 和 Vue 中如何實(shí)現(xiàn)這一點(diǎn)。
在 React 中的實(shí)現(xiàn):
- 創(chuàng)建一個(gè)封裝的 Axios 實(shí)例,以便于應(yīng)用中的多個(gè)組件共享相同的配置和取消令牌。
// axiosInstance.js
import axios from 'axios';
const instance = axios.create();
export default instance;
- 在組件中使用這個(gè)封裝的 Axios 實(shí)例,并結(jié)合組件的狀態(tài)管理來處理取消請求的邏輯。
// YourComponent.js
import React, { useState } from 'react';
import axiosInstance from './axiosInstance';
function YourComponent() {
const [loading, setLoading] = useState(false);
const [data, setData] = useState(null);
const source = axiosInstance.CancelToken.source();
const fetchData = async () => {
try {
setLoading(true);
const response = await axiosInstance.get('/api/some-endpoint', {
cancelToken: source.token
});
setData(response.data);
setLoading(false);
} catch (error) {
if (axiosInstance.isCancel(error)) {
console.log('請求被取消:', error.message);
} else {
// 處理其他錯(cuò)誤
}
setLoading(false);
}
};
const cancelRequest = () => {
source.cancel('請求被用戶取消');
};
return (
<div>
{loading ? <p>Loading...</p> : <p>{data}</p>}
<button onClick={fetchData}>Fetch Data</button>
<button onClick={cancelRequest}>取消請求</button>
</div>
);
}
export default YourComponent;
在 Vue 中的實(shí)現(xiàn):
- 創(chuàng)建一個(gè)封裝的 Axios 實(shí)例,同樣可以讓多個(gè)組件共享相同的配置和取消令牌。
// axiosInstance.js
import axios from 'axios';
const instance = axios.create();
export default instance;
- 在組件中使用這個(gè)封裝的 Axios 實(shí)例,并結(jié)合組件的狀態(tài)管理來處理取消請求的邏輯。
<template>
<div>
<p v-if="loading">Loading...</p>
<p v-else>{{ data }}</p>
<button @click="fetchData">Fetch Data</button>
<button @click="cancelRequest">取消請求</button>
</div>
</template>
<script>
import axiosInstance from './axiosInstance';
export default {
data() {
return {
loading: false,
data: null,
source: axiosInstance.CancelToken.source()
};
},
methods: {
async fetchData() {
try {
this.loading = true;
const response = await axiosInstance.get('/api/some-endpoint', {
cancelToken: this.source.token
});
this.data = response.data;
this.loading = false;
} catch (error) {
if (axiosInstance.isCancel(error)) {
console.log('請求被取消:', error.message);
} else {
// 處理其他錯(cuò)誤
}
this.loading = false;
}
},
cancelRequest() {
this.source.cancel('請求被用戶取消');
}
}
};
</script>
原理
Axios 取消請求的原理是基于底層網(wǎng)絡(luò)請求庫(如 XMLHttpRequest 或 Fetch)提供的中止機(jī)制。當(dāng)調(diào)用取消令牌的 cancel 方法時(shí),Axios 會觸發(fā)中止底層的網(wǎng)絡(luò)請求,從而終止正在進(jìn)行的請求過程。
具體來說,以下是 Axios 取消請求的原理:
- 創(chuàng)建 CancelToken 對象: 在發(fā)起請求之前,可以通過 axios.CancelToken.source() 方法創(chuàng)建一個(gè) CancelToken 對象,并獲取其中的 token。這個(gè) token 是一個(gè)用于標(biāo)識該請求的令牌。
- 關(guān)聯(lián) CancelToken: 將創(chuàng)建的 CancelToken 對象中的 token 關(guān)聯(lián)到請求的配置中,通過 cancelToken 參數(shù)。這告訴 Axios 在取消令牌觸發(fā)時(shí)要取消這個(gè)請求。
- 取消請求: 當(dāng)想要取消請求時(shí),調(diào)用 CancelToken 對象中的 cancel 方法,并提供一個(gè)取消的原因。這會觸發(fā) Axios 內(nèi)部的邏輯,導(dǎo)致底層的網(wǎng)絡(luò)請求被中止。
- 捕獲取消錯(cuò)誤: 如果請求在取消前已經(jīng)發(fā)出,Axios 會拋出一個(gè)名為 Cancel 的錯(cuò)誤??梢允褂?axios.isCancel(error) 來檢查是否是取消錯(cuò)誤。在 .catch 部分處理這個(gè)取消錯(cuò)誤。
底層 XMLHttpRequest 和 Fetch API 都提供了終止請求的機(jī)制。當(dāng)取消請求時(shí),Axios 會調(diào)用底層網(wǎng)絡(luò)請求的相應(yīng)中止方法,例如 xhr.abort() 或 fetch.abort(),從而使網(wǎng)絡(luò)請求停止并拋出取消錯(cuò)誤。這個(gè)機(jī)制允許有效地取消正在進(jìn)行的請求,避免不必要的數(shù)據(jù)傳輸和處理。