面試官:如何中斷已發(fā)出去的請求?
點(diǎn)擊上方“碼農(nóng)突圍”,馬上關(guān)注
這里是碼農(nóng)充電第一站,回復(fù)“666”,獲取一份專屬大禮包 真愛,請?jiān)O(shè)置“星標(biāo)”或點(diǎn)個(gè)“在看 作者:紫圣 https://juejin.cn/post/7033906910583586829
推薦閱讀:axios解析之cancelToken取消請求原理[2]
AbortController
AbortController():AbortController()構(gòu)造函數(shù)創(chuàng)建一個(gè)新的 AbortController 對象實(shí)例
signal:signal 屬性返回一個(gè) AbortSignal 對象實(shí)例,它可以用來 with/about 一個(gè)Web(網(wǎng)絡(luò))請求
abort():終止一個(gè)尚未完成的Web(網(wǎng)絡(luò))請求,它能夠終止 fetch 請求,任何響應(yīng)Body的消費(fèi)者和流
Fetch 中斷請求
const controller = new AbortController();
let signal = controller.signal;
console.log('signal 的初始狀態(tài): ', signal);
const downloadBtn = document.querySelector('.download');
const abortBtn = document.querySelector('.abort');
downloadBtn.addEventListener('click', fetchVideo);
abortBtn.addEventListener('click', function() {
controller.abort();
console.log('signal 的中止?fàn)顟B(tài): ', signal);
});
function fetchVideo() {
//...
fetch(url, {signal}).then(function(response) {
//...
}).catch(function(e) {
reports.textContent = 'Download error: ' + e.message;
})
}
復(fù)制代碼


線上運(yùn)行示例[4] (代碼來源于MDN[5])

axios 中斷請求
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('https://mdn.github.io/dom-examples/abort-api/sintel.mp4', {
cancelToken: source.token
}).catch(function (thrown) {
// 判斷請求是否已中止
if (axios.isCancel(thrown)) {
// 參數(shù) thrown 是自定義的信息
console.log('Request canceled', thrown.message);
} else {
// 處理錯(cuò)誤
}
});
// 取消請求(message 參數(shù)是可選的)
source.cancel('Operation canceled by the user.');
復(fù)制代碼



const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函數(shù)接收一個(gè) cancel 函數(shù)作為參數(shù)
cancel = c;
})
});
// 取消請求
cancel('Operation canceled by the user.');
復(fù)制代碼
線上運(yùn)行示例[6] (代碼來源于MDN[7])
umi-request 中斷請求
umi 項(xiàng)目中使用 CancelToken 中止請求
import request from '@/utils/request';
const CancelToken = request.CancelToken;
let cancel: any;
// 合同文件上傳 OSS
export async function uploadContractFileToOSS(postBody: Blob): Promise<any> {
return request(`/fms/ossUpload/financial_sys/contractFile`, {
method: "POST",
data: postBody,
requestType: 'form',
// 傳遞一個(gè) executor 函數(shù)到 CancelToken 的構(gòu)造函數(shù)來創(chuàng)建一個(gè) cancel token
cancelToken: new CancelToken((c) => {
cancel = c
})
})
}
// 取消合同文件上傳
export async function cancelUploadFile() {
return cancel && cancel()
}
復(fù)制代碼
*uploadContractFileToOSS({ payload }: AnyAction, { call, put }: EffectsCommandMap): any {
const response = yield call(uploadContractFileToOSS, payload);
yield put({
type: 'save',
payload: {
uploadOSSResult: response?.data,
}
})
return response?.data
},
*cancelUploadFile(_: AnyAction, { call }: EffectsCommandMap): any {
const response = yield call(cancelUploadFile)
return response
},
復(fù)制代碼
// 發(fā)起請求
dispatch({
type: 'contract/fetchContractFiles',
payload: {
contractId: `${id}`,
}
})
// 取消請求
dispatch({
type: "contract/cancelUploadFile"
})
復(fù)制代碼
const errorHandler = (error: { response: Response }): Response => {
const { response } = error;
notification.destroy()
if (response && response.status) {
const errorText = codeMessage[response.status] || response.statusText;
const { status, url } = response;
notification.error({
message: `請求錯(cuò)誤 ${status}: ${url}`,
description: errorText,
});
} else if (error?.['type'] === 'TypeError') {
notification.error({
description: '您的網(wǎng)絡(luò)發(fā)生異常,無法連接服務(wù)器',
message: '網(wǎng)絡(luò)異常',
});
} else if (error?.['request']?.['options']?.['cancelToken']) {
notification.warn({
description: '當(dāng)前請求已被取消',
message: '取消請求',
});
} else if (!response) {
notification.error({
description: '您的網(wǎng)絡(luò)發(fā)生異常,無法連接服務(wù)器',
message: '網(wǎng)絡(luò)異常',
});
} else {
notification.error({
description: '請聯(lián)系網(wǎng)站開發(fā)人員處理',
message: '未知錯(cuò)誤',
});
}
return response;
};
復(fù)制代碼
-End-
最近有一些小伙伴,讓我?guī)兔φ乙恍?nbsp;面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網(wǎng)盤了,歡迎下載!
點(diǎn)擊??卡片,關(guān)注后回復(fù)【面試題】即可獲取
評論
圖片
表情

