巧妙的通過改變 Promise 狀態(tài)實現(xiàn)取消請求
封裝之后外部拿不到 xhr 實例,內(nèi)部通過判斷傳入的 cancelToken.promise 的狀態(tài)達(dá)到取消請求的效果
// class CannelToken
class CannelToken {
promise
reason
constructor(executor) {
let resolvePromise
this.promise = new Promise(resolve => {
// 將 resolve 函數(shù)保存,需要將 promise 狀態(tài)改為 resolved 的時候再調(diào)用
resolvePromise = resolve
})
// 執(zhí)行實例化時傳入的函數(shù),(message) => { // ... } 作為參數(shù)
// 將 resolvePromise 暴露
executor(message => {
if (this.reason) {
return
}
this.reason = message
resolvePromise(this.reason)
})
}
}
// xhr.ts
// 請求配置 config 中可能有 cancelToken 屬性
// config.cancelToken 是類 CancelToken 的實例,保存了 promise
if (config.cancelToken) {
// 當(dāng) promise 從 pending 狀態(tài)變?yōu)?fulfilled 就會執(zhí)行以下代碼
config.cancelToken.promise.then(res => {
request.abort()
reject(res)
})
}
request.sent()
// demo 發(fā)請求
let cancel
axios.get('cancel/get', {
cancelToken: new CancelToken(function (c) {
// 參數(shù) c 就是 (message) => { // ... }
cancel = c
})
})
// 調(diào)用 cancel 就可以調(diào)用 resolvePromise,從而改變 promise 的狀態(tài)
// 然后執(zhí)行 xhr.ts 中的 promise.then
cancel()