最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端axios取消請(qǐng)求總結(jié)詳解

 更新時(shí)間:2022年10月15日 08:27:41   作者:青天訣  
這篇文章主要為大家介紹了前端axios取消請(qǐng)求總結(jié)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

應(yīng)用場(chǎng)景

取消請(qǐng)求在前端有時(shí)候會(huì)用到,以下是兩個(gè)工作中可能會(huì)用到的場(chǎng)景

  • tab切換時(shí)刷新某個(gè)列表數(shù)據(jù),如果他們共用一個(gè)變量存儲(chǔ)數(shù)據(jù)列表,當(dāng)請(qǐng)求有延時(shí),可能會(huì)導(dǎo)致兩個(gè)tab數(shù)據(jù)錯(cuò)亂;
  • 導(dǎo)出文件或下載文件時(shí),中途取消 。

如何取消請(qǐng)求

取消http請(qǐng)求,axios文檔里提供了兩種用法:

第一種:使用 CancelToken

const { CancelToken, isCanCel } = axios;
const source = CancelToken.source();
axios.get('/user/12345', {
  cancelToken: source.token
}).catch(thrown => {
  if (isCancel(thrown)) {
    // 獲取 取消請(qǐng)求 的相關(guān)信息
    console.log('Request canceled', thrown.message);
  } else {
    // 處理其他異常
  }
});
axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})
// 取消請(qǐng)求。參數(shù)是可選的,參數(shù)傳遞一個(gè)取消請(qǐng)求的相關(guān)信息,在 catch 鉤子函數(shù)里能獲取到
source.cancel('Operation canceled by the user.');

第二種:給構(gòu)造函數(shù) CancelToken 傳遞一個(gè) executor 函數(shù)作為參數(shù)。這種方法的好處是,可以用同一個(gè) cancel token 來(lái)取消多個(gè)請(qǐng)求

const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // 參數(shù) c 也是個(gè)函數(shù)
    cancel = c;
  })
});
// 取消請(qǐng)求,參數(shù)用法同上
cancel();

項(xiàng)目中用法示例

在一個(gè)真實(shí)的項(xiàng)目中,一般都會(huì)對(duì)axios進(jìn)行二次封裝,針對(duì)請(qǐng)求、響應(yīng)、狀態(tài)碼、code等做處理。貼一個(gè)項(xiàng)目里常用的request.js:

import axios from 'axios'
import store from '@/store'
import { getToken } from '@/utils/auth'
// 創(chuàng)建一個(gè) axios 實(shí)例,并改變默認(rèn)配置
const service = axios.create({
  baseURL: process.env.BASE_API, // api 的 base_url
  timeout: 5000 // request timeout
})
// 請(qǐng)求攔截
service.interceptors.request.use(
  config => {
    // Do something before request is sent
    if (store.getters.token) {
      // 讓每個(gè)請(qǐng)求攜帶token-- ['X-Token']為自定義key 請(qǐng)根據(jù)實(shí)際情況自行修改
      config.headers['X-Token'] = getToken()
    }
    return config
  },
  error => {
    // Do something with request error
    console.log(error) // for debug
    Promise.reject(error)
  }
)
// 響應(yīng)攔截
service.interceptors.response.use(
  response => response,
  error => {
    alert(error)
    return Promise.reject(error)
  }
)
export default service

對(duì)于某一個(gè)請(qǐng)求添加取消的功能,要在調(diào)用api時(shí),加上cancelToken選項(xiàng),使用時(shí)的示例:

// api.js
import request from 'request'
export function getUsers(page, options) {
  return request({
    url: 'api/users',
    params: {
      page
    },
    ...options
  })
}
// User.vue
import { CancelToken, isCancel } from 'axios'
import { getUsers } from 'api'
...
cancel: null
...
toCancel() {
  this.cancel('取消請(qǐng)求')
}
getUsers(1,
  {
    cancelToken:  new CancelToken(c => (this.cancel = c))
  }
)
.then(...)
.catch(err => {
  if (isCancel) {
    console.log(err.message)
  } else {
    ...
  }
})

以上,我們就可以順順利利地使用封裝過(guò)的axios,取消某一個(gè)請(qǐng)求了。其原理無(wú)非就是把cancelToken的配置項(xiàng),在調(diào)用api時(shí)加上,然后就可以在業(yè)務(wù)代碼取消特定請(qǐng)求了。

批量取消請(qǐng)求

在 document 里的第二種方法已經(jīng)說(shuō)過(guò):通過(guò)指定同一個(gè)cancel token來(lái)取消。但是,在上面的項(xiàng)目示例中,不能控制拿到相同的cancel token。我們可以換個(gè)思路:用數(shù)組保存每個(gè)需要取消的cancel token,然后逐一調(diào)用數(shù)組里的每一項(xiàng)即可:

// User.vue
import { CancelToken, isCancel } from 'axios'
import { getUsers } from 'api'
...
cancel: []
...
toCancel() {
  while (this.cancel.length > 0) {
    this.cancel.pop()('取消請(qǐng)求')
  }
}
getUser1(1,
  {
    cancelToken:  new CancelToken(c1 => (this.cancel.push(c1)))
  }
)
getUser2(2,
 {
  cancelTokem: new CancleTokem(c2 => (this.cancel.push(c2)))
 }
)

切換路由時(shí),取消請(qǐng)求

上面講了取消一個(gè)請(qǐng)求及頁(yè)面內(nèi)批量abort的方法,此外,還有一種需求——切換路由時(shí),取消所有。 這里不詳細(xì)贅述了,大概思路就是在請(qǐng)求攔截器里,統(tǒng)一加個(gè)token,并設(shè)置全局變量source控制一個(gè)cancel token,在路由變化時(shí)調(diào)用cancel方法。

http.interceptors.request.use(config => {
    config.cancelToken = store.source.token
    return config
}, err => {
    return Promise.reject(err)
})
router.beforeEach((to, from, next) => {
    const CancelToken = axios.CancelToken
    store.source.cancel && store.source.cancel()
    store.source = CancelToken.source()
    next()
})
// 全局變量
store = {
    source: {
        token: null,
        cancel: null
  }
}

取消請(qǐng)求的實(shí)現(xiàn)原理

cancelToken的source方法維護(hù)了一個(gè)對(duì)象,里面包括了token令牌和cancel方法,token來(lái)自與構(gòu)造函數(shù)CancelToken,調(diào)用cancel方法后,token的promise狀態(tài)為resolved,進(jìn)而又調(diào)用了xhr的abort方法,取消請(qǐng)求成功。 來(lái)分析下取消請(qǐng)求是怎么實(shí)現(xiàn)的,先從一個(gè)簡(jiǎn)單的取消請(qǐng)求的例子開(kāi)始:

var CancelToken = axios.CancelToken;
var source = CancelToken.source();
axios.get('/get?name=xmz', {
    cancelToken : source.token
}).then((response)=>{
    console.log('response', response)
}).catch((error)=>{
    if(axios.isCancel(error)){
        console.log('取消請(qǐng)求傳遞的消息', error.message)
    }else{
        console.log('error', error)
    }
})
// 取消請(qǐng)求
source.cancel('取消請(qǐng)求傳遞這條消息');

這就是一個(gè)簡(jiǎn)單的取消請(qǐng)求的例子,那么就從最開(kāi)始的axios.CancelToken來(lái)看,先去axios/lib/axios.js文件中。

axios.CancelToken = require('./cancel/CancelToken');

不費(fèi)吹灰之力,就找到了CancelToken,在例子中我們調(diào)用了source方法,那么就去axios/lib/cancel/CancelToken.js文件中看看這個(gè)source方法到底是干什么的?

CancelToken.source = function(){
    var cancel;
    var token = new CancelToken(function executor(c) {
        cancel = c
    })
    return {
        token : token,
        cancel : cancel
    }
}

source方法很簡(jiǎn)單,就是返回一個(gè)具有token和cancel屬性的對(duì)象,但是token和cancel都是通過(guò)CancelToken這個(gè)構(gòu)造函數(shù)來(lái)的,那么還在這個(gè)文件中向上看,找到CancelToken函數(shù)。

function CancelToken (executor){
    // ...
    // 判斷executor是一個(gè)函數(shù),不然就報(bào)錯(cuò)
    var resolvePromise;
    this.promise = new Promise(function(resolve){
        resolvePromise = resolve;
    })
    var token = this;
    // 以上token現(xiàn)在有一個(gè)promise屬性,是一個(gè)未成功的promise對(duì)象;
    executor(function cancel(message){
        if(token.reason){
            return;
        }
        token.reason = new Cancel(message);
        resolvePromise(token.reason);
    })
    // 這個(gè)cancel函數(shù)就是 上面函數(shù)中的cancel,也就是source.cancel;
}

現(xiàn)在知道了source.cancel是一個(gè)函數(shù),souce.token是一個(gè)實(shí)例化對(duì)象,暫時(shí)就知道這些,繼續(xù)看文章最開(kāi)始的例子,接下來(lái)是去發(fā)送請(qǐng)求了,最下面還有一行代碼是執(zhí)行souce.cancel(); souce.cancel就是用來(lái)觸發(fā)取消請(qǐng)求的函數(shù)。 現(xiàn)在再回頭來(lái)看,上面的cancel函數(shù),cancel執(zhí)行,給token加了一個(gè)reason屬性,那么看下這個(gè)reason屬性是什么吧,看下這個(gè)Cancel構(gòu)造函數(shù),在axios/lib/cancel/Cancel.js文件中

function Cancel(message){
    this.message = message
}

Cancel特別簡(jiǎn)單就是給實(shí)例化對(duì)象添加一個(gè)message屬性,所以現(xiàn)在token.reason是一個(gè)具有message屬性的對(duì)象了。 繼續(xù)回到cancel函數(shù)中,resolvePromise函數(shù)執(zhí)行了,那么token.promise對(duì)象,這個(gè)原本未變成,成功狀態(tài)的promise,變成了成功狀態(tài)了,并且將token.reason對(duì)象傳遞過(guò)去了。 簡(jiǎn)單總結(jié)一下,執(zhí)行取消函數(shù),就是讓token的promise的狀態(tài)變成了成功; 好了,突然發(fā)現(xiàn)分析中斷了,變成成功狀態(tài)又怎樣了,怎么取消的呢?雖然現(xiàn)在的同步代碼都執(zhí)行完了,但是請(qǐng)求還沒(méi)發(fā)送出去呢,我們還要去看發(fā)送請(qǐng)求的函數(shù)

在分析發(fā)送請(qǐng)求之前,再看下最開(kāi)始的例子,和最普通的發(fā)送一個(gè)get請(qǐng)求還是有一點(diǎn)區(qū)別的,配置對(duì)象中多了,一個(gè)cancelToken的屬性,值是token,到底起了什么作用呢,去axios/lib/adapters/xhr.js中一探究竟(這里只截取其中關(guān)于cancelToken的部分)。

// 在發(fā)送請(qǐng)求之前,驗(yàn)證了cancelToken,看來(lái)此處就是用來(lái)取消請(qǐng)求的;
if(config.cancelToken){
    // 具體是如何取消的,是在這個(gè)判斷內(nèi)定義的;
    config.cancelToken.promise.then(function(cancel){
        request.abort();
        reject(cancel);
        request = null;
    })
}
// 發(fā)送請(qǐng)求
request.send(requestData);

仔細(xì)看這只是一個(gè)promise的then函數(shù),只有在promise的狀態(tài)變成成功后才會(huì)執(zhí)行,而剛才我們分析了,cancel就是讓這個(gè)promise的狀態(tài)變成成功,所以如果執(zhí)行了,取消請(qǐng)求的函數(shù),這個(gè)then就會(huì)執(zhí)行,取消發(fā)送請(qǐng)求,并且把發(fā)送請(qǐng)求的promise變成reject,被axiox.get().catch()捕獲; 流程已經(jīng)清楚了,最后再總結(jié)一下: 執(zhí)行cancel是讓token的promise變成成功,在真正發(fā)送請(qǐng)求之前,驗(yàn)證token.promise的狀態(tài)是否已經(jīng)變了,如果變了,就取消請(qǐng)求,就是這樣一個(gè)簡(jiǎn)單的思想來(lái)進(jìn)行取消請(qǐng)求的。

以上就是axios取消請(qǐng)求總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于axios取消請(qǐng)求的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vuejs2.0實(shí)現(xiàn)分頁(yè)組件使用$emit進(jìn)行事件監(jiān)聽(tīng)數(shù)據(jù)傳遞的方法

    vuejs2.0實(shí)現(xiàn)分頁(yè)組件使用$emit進(jìn)行事件監(jiān)聽(tīng)數(shù)據(jù)傳遞的方法

    這篇文章主要介紹了vuejs2.0實(shí)現(xiàn)分頁(yè)組件使用$emit進(jìn)行事件監(jiān)聽(tīng)數(shù)據(jù)傳遞的方法,非常不錯(cuò),具有參考借鑒價(jià)值,,需要的朋友可以參考下
    2017-02-02
  • Electron-vue腳手架改造vue項(xiàng)目的方法

    Electron-vue腳手架改造vue項(xiàng)目的方法

    這篇文章主要介紹了Electron-vue腳手架改造vue項(xiàng)目的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • vant中如何修改用戶(hù)的頭像

    vant中如何修改用戶(hù)的頭像

    這篇文章主要介紹了vant中如何修改用戶(hù)的頭像,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue解決跨域問(wèn)題的方法

    vue解決跨域問(wèn)題的方法

    本文主要介紹了前后端分離項(xiàng)目中的跨域問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • vue axios sessionID每次請(qǐng)求都不同的原因以及修改方式

    vue axios sessionID每次請(qǐng)求都不同的原因以及修改方式

    這篇文章主要介紹了vue axios sessionID每次請(qǐng)求都不同的原因以及修改方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 面試官問(wèn)你Vue2的響應(yīng)式原理該如何回答?

    面試官問(wèn)你Vue2的響應(yīng)式原理該如何回答?

    可能很多小伙伴之前都了解過(guò)?Vue2實(shí)現(xiàn)響應(yīng)式的核心是利用了ES5的Object.defineProperty?但是面對(duì)面試官時(shí)如果只知道一些模糊的概念。只有深入底層了解響應(yīng)式的原理,才能在關(guān)鍵時(shí)刻對(duì)答如流,本文就來(lái)和大家詳細(xì)聊聊,感興趣的可以收藏一下
    2022-12-12
  • Vue項(xiàng)目中使用iView組件庫(kù)設(shè)置樣式不生效的解決方案

    Vue項(xiàng)目中使用iView組件庫(kù)設(shè)置樣式不生效的解決方案

    這篇文章主要介紹了Vue項(xiàng)目中使用iView組件庫(kù)設(shè)置樣式不生效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • QT和vue交互的實(shí)現(xiàn)示例

    QT和vue交互的實(shí)現(xiàn)示例

    本文主要介紹了QT和vue交互的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • vue DatePicker日期選擇器時(shí)差8小時(shí)問(wèn)題

    vue DatePicker日期選擇器時(shí)差8小時(shí)問(wèn)題

    這篇文章主要介紹了vue DatePicker日期選擇器時(shí)差8小時(shí)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 每天學(xué)點(diǎn)Vue源碼之vm.$mount掛載函數(shù)

    每天學(xué)點(diǎn)Vue源碼之vm.$mount掛載函數(shù)

    這篇文章主要介紹了vm.$mount掛載函數(shù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03

最新評(píng)論

中卫市| 大同县| 罗城| 浪卡子县| 金寨县| 宜川县| 临洮县| 通化县| 固安县| 道真| 广德县| 托克托县| 东至县| 商南县| 防城港市| 乌兰县| 霍城县| 那曲县| 田林县| 方山县| 南澳县| 曲周县| 福州市| 南部县| 台南市| 遂宁市| 台中市| 福鼎市| 兴文县| 巴林右旗| 岳阳市| 宝应县| 泽库县| 和平县| 沭阳县| 宜黄县| 遂平县| 昌平区| 郑州市| 永泰县| 九江县|