日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

axios某一接口失败后不调用_axios 源码系列之如何取消请求

發(fā)布時間:2023/12/10 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 axios某一接口失败后不调用_axios 源码系列之如何取消请求 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我們在前后端交互的過程中,通常是通過請求接口來實現(xiàn)的,而一個頁面中的交互又非常復(fù)雜,例如需要多次頻繁請求同一個接口,或者在接口還沒返回時就要切換路由等。這些都需要對接口請求的時機(jī)或者請求接口之后進(jìn)行處理,避免一些無用的請求或者接口返回順序的差異。

  • 防抖:在用戶快速地交互過程中,只使用最后一次交互產(chǎn)生的數(shù)據(jù),然后再發(fā)起請求,例如頻繁的切換 tab,或者快速輸入數(shù)據(jù)等;
  • 鎖狀態(tài):在上一個接口沒有返回數(shù)據(jù)時,交互狀態(tài)一直處于 loading 的鎖定狀態(tài),直到數(shù)據(jù)正確返回或者超時等異常;
  • 取消上一個請求:在發(fā)起下一個請求前,把之前的請求取消掉;
  • 前兩種方式,是在發(fā)起請求前進(jìn)行控制,即控制發(fā)起請求的時機(jī),而當(dāng)請求發(fā)出之后則不再控制;而最終一種方式則是取消中斷還在路上的請求,然后再發(fā)起一個新的請求,不用管發(fā)起的時機(jī)。這幾種方式也要看業(yè)務(wù)的需要,選擇最適合的即可。

    我們在之前的如何實現(xiàn) axios 的自定義適配器 adapter文章里,略過了 axios 是如何主動取消當(dāng)前請求的。今天我們就將一下在 axios 中如何取消之前發(fā)起的請求,源碼中又是怎樣實現(xiàn)的。

    1. 主動取消之前發(fā)起的請求

    我們先來看下 axios 中取消請求的用法:

    const CancelToken = axios.CancelToken;// 返回兩個字段,{ token, cancel } // token用于表示某個請求,是一個Promise類型 // cancel是一個方法,當(dāng)被調(diào)用時,則取消token注入的那個請求 const source = CancelToken.source();axios.get('/user/12345', {cancelToken: source.token, // 將token注入到請求中}).catch(function (thrown) {// 判斷是否是因主動取消導(dǎo)致的if (axios.isCancel(thrown)) {console.log('Request canceled', thrown.message);} else {// handle errorconsole.error(thrown);}});axios.post('/user/12345',{name: 'new name',},{cancelToken: source.token,} );// 主動取消請求 // cancel方法會把注入的同一個token的請求方法一并取消掉 // 上面的get和post請求都會被取消掉 // cancel the request (the message parameter is optional) source.cancel('Operation canceled by the user.');

    從 demo 上來看,用法很簡單,token 和 cancel 的關(guān)系對應(yīng)上即可。

    官方例子中還有一種取消請求的方式,這個我們放在后面講,更容易理解一些。

    2. 源碼解析

    取消請求的方法在 https://github.com/axios/axios/tree/master/lib/cancel 的目錄中,3 個文件:

    • Cancel: Cancel 類,message 和__CANCEL__屬性,用于標(biāo)識取消的某個請求;
    • isCancel: 判斷當(dāng)前參數(shù)是否是 Cancel 的實例;
    • CancelToken: 主流程,創(chuàng)建 Cancel 實例和取消的方法;

    我們主要來看下 CancelToken 中的整個流程。

    2.1 source 方法

    source 作為取消請求的入口,我們就先來看下 source 方法。

    // 創(chuàng)建token和cancel方法 CancelToken.source = function source() {var cancel;// token為 CancelToken 的實例,包含 promise 和 reason 兩個屬性// 同時把 executor 中的參數(shù)給到 cancel// 即CancelToken有一個回調(diào)函數(shù),而這個回調(diào)函數(shù)的參數(shù)也是一個函數(shù)// CancelToken怎么執(zhí)行,我們接著看!var token = new CancelToken(function executor(c) {cancel = c;});return {token: token,cancel: cancel,}; };

    2.2 CancelToken

    CancelToken 用來取消請求,但我理解起來,思路非常的繞,我們一點點來剖析:

    function CancelToken(executor) {if (typeof executor !== 'function') {throw new TypeError('executor must be a function.');}// 創(chuàng)建一個Promise的實例,// 當(dāng)resolvePromise執(zhí)行時,this.promise變?yōu)閒ulfilled狀態(tài)var resolvePromise;this.promise = new Promise(function promiseExecutor(resolve) {resolvePromise = resolve;});// new一個實例時,會立即執(zhí)行CancelToken的回調(diào)函數(shù)executor方法// executor的參數(shù)也是一個函數(shù),即上面的cancel就是當(dāng)前的cancel函數(shù)體// 當(dāng)executor的回調(diào)函數(shù)cancel執(zhí)行時,會給當(dāng)前CancelToken創(chuàng)建一個reason屬性,這個屬性是Cancel的實例// 并執(zhí)行resolvePromise方法,將reason實例穿進(jìn)去;執(zhí)行后this.promise變?yōu)閒ulfilled狀態(tài)var token = this;executor(function cancel(message) {if (token.reason) {// Cancellation has already been requestedreturn;}token.reason = new Cancel(message);resolvePromise(token.reason);}); }

    也就是說會先創(chuàng)建一個 CancelToken 的實例 token,同時,將 CancelToken 中回調(diào)函數(shù)的參數(shù)給到了 cancel。當(dāng) cancel 執(zhí)行時,則 token 中的 promise 屬性則會從 pending 狀態(tài)變?yōu)?fulfilled 狀態(tài),那么 promise 上掛載的then()方法也就可以繼續(xù)執(zhí)行了。

    2.3 adapter

    在調(diào)用 cancel 方法后,請求中是怎么操作的呢?我們看下adapter/xhr.js中的代碼:

    if (config.cancelToken) {// config.cancelToken就是上面創(chuàng)建的token// 當(dāng)token.promise變?yōu)閒ulfilled狀態(tài)后,就可以執(zhí)行后續(xù)的鏈?zhǔn)讲僮?/ Handle cancellationconfig.cancelToken.promise.then(function onCanceled(cancel) {if (!request) {return;}// 取消當(dāng)前的請求request.abort();// 將Cancel的實例cancel給到rejectreject(cancel);// Clean up requestrequest = null;}); }

    當(dāng)我們使用 axios 的 catch 捕獲內(nèi)部拋出的異常時,就可以通過isCancel判斷是否是因主動取消請求導(dǎo)致的異常:

    axios.get('/user/12345', {cancelToken: source.token, // 將token注入到請求中}).catch(function (thrown) {// 判斷是否是因主動取消導(dǎo)致的if (axios.isCancel(thrown)) {console.log('Request canceled', thrown.message);} else {// handle errorconsole.error(thrown);}});

    現(xiàn)在再來看下 cancel 執(zhí)行的整個流程,就會清晰流暢很多。

    3. 取消請求的另一種方式

    我們在第 1 節(jié)還留著一個問題,axios 取消請求還有另一種方式,即直接使用 CancelToken 類。

  • token: 我們在上面的 source()方法中就能看到,傳給 axios 參數(shù)的 token 就是 CancenToken 的實例,這里直接使用new CancelToken()的返回值也是可以的;
  • cancel: source()中的 cancel 就是 CancelToken 的回調(diào)函數(shù) executor 的回調(diào)函數(shù);
  • const CancelToken = axios.CancelToken; let cancel;axios.get('/user/12345', {// CancelToken創(chuàng)建的cancelToken: new CancelToken(function executor(c) {// An executor function receives a cancel function as a parametercancel = c;}), });// cancel the request cancel();

    其實我們發(fā)現(xiàn),source()方法,只是給我們額外又封裝了一下,簡單的返回了 token 和 cancel,但本質(zhì)還是 CancelToken 中的東西。

    4. 總結(jié)

    在取消請求的過程中,token 要和 cancel 方法保持對應(yīng)關(guān)系,即都在一個對象里;若其他的請求也要取消時,可以額外再生成一組 token 和 cancel。同時,這里還用到了 Promise 的一個機(jī)制,只有在當(dāng)前 Promise 變更為 fulfilled 狀態(tài)后,才能執(zhí)行后面的 then 等操作。

    更多文章歡迎查看我的博客:

    蚊子的前端博客?www.xiabingbao.com

    總結(jié)

    以上是生活随笔為你收集整理的axios某一接口失败后不调用_axios 源码系列之如何取消请求的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。