<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官:如何中斷已發(fā)出去的請求?

          共 5168字,需瀏覽 11分鐘

           ·

          2022-01-04 08:14


          ? 面試官:請求已經(jīng)發(fā)出去了,如何取消掉這個已經(jīng)發(fā)出去的請求?

          面試者:(腦海里立馬產(chǎn)生一個疑惑:已經(jīng)發(fā)出去的請求還能取消掉?) 這個......這個......還真不知道。

          面試完,馬上找度娘.....

          推薦閱讀:axios解析之cancelToken取消請求原理[2]

          AbortController

          AbortController[3] 接口表示一個控制器對象,可以根據(jù)需要終止一個或多個Web請求。

          • AbortController():AbortController()構(gòu)造函數(shù)創(chuàng)建一個新的 AbortController 對象實(shí)例

          • signal:signal 屬性返回一個 AbortSignal 對象實(shí)例,它可以用來 with/about 一個Web(網(wǎng)絡(luò))請求

          • abort():終止一個尚未完成的Web(網(wǎng)絡(luò))請求,它能夠終止 fetch 請求,任何響應(yīng)Body的消費(fèi)者和流

          Fetch 中斷請求

          Fetch 是 Web 提供的一個用于獲取資源的接口,如果要終止 fetch 請求,則可以使用 Web 提供的 AbortController 接口。

          首先我們使用 AbortController() 構(gòu)造函數(shù)創(chuàng)建一個控制器,然后使用 AbortController.signal 屬性獲取其關(guān)聯(lián) AbortSignal 對象的引用。當(dāng)一個 fetch request 初始化時,我們把 AbortSignal 作為一個選項(xiàng)傳遞到請求對象 (如下:{signal}) 。這將信號和控制器與獲取請求相關(guān)聯(lián),然后允許我們通過調(diào)用 AbortController.abort() 中止請求。

          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ù)制代碼

          當(dāng)我們中止請求后,網(wǎng)絡(luò)請求變成了如下所示的情況:

          我們再來看看 AbortSignal 中止前和中止后的狀態(tài):

          可以看到,AbortSignal 對象的 aborted 屬性由初始時的 false 變成了中止后的 true 。

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

          AbortControllter 有兼容性問題,如下:

          axios 中斷請求

          axions 中斷請求有兩種方式:

          方式一

          使用 CancelToken.souce 工廠方法創(chuàng)建一個 cancel token,代碼如下:

          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?{
          ????//?處理錯誤
          ??}
          });

          //?取消請求(message?參數(shù)是可選的)
          source.cancel('Operation?canceled?by?the?user.');
          復(fù)制代碼

          中止后的網(wǎng)絡(luò)請求變成如下所示:

          我們再來看看初始時和中止后的 souce 狀態(tài):

          可以看到,初始時和中止后的 source 狀態(tài)并沒還有發(fā)生改變。那么我們是如何判斷請求的中止?fàn)顟B(tài)呢?axios 為我們提供了一個 isCancel() 方法,用于判斷請求的中止?fàn)顟B(tài)。isCancel() 方法的參數(shù),就是我們在中止請求時自定義的信息。

          方式二

          通過傳遞一個 executor 函數(shù)到 CancelToken 的構(gòu)造函數(shù)來創(chuàng)建一個 cancel token:

          const?CancelToken?=?axios.CancelToken;
          let?cancel;

          axios.get('/user/12345',?{
          ??cancelToken:?new?CancelToken(function?executor(c)?{
          ????//?executor?函數(shù)接收一個?cancel?函數(shù)作為參數(shù)
          ????cancel?=?c;
          ??})
          });

          //?取消請求
          cancel('Operation?canceled?by?the?user.');
          復(fù)制代碼

          瀏覽器運(yùn)行結(jié)果與方式一一致,此處不再贅述。

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

          umi-request 中斷請求

          umi-request 基于 fetch 封裝, 兼具 fetch 與 axios 的特點(diǎn), 中止請求與 fetch 和 axios 一致不再過多贅述,詳情可見官方文檔 中止請求[8]

          需要注意的是 AbortController 在低版本瀏覽器polyfill有問題,umi-request 在某些版本中并未提供 AbortController 的方式中止請求。

          umi 項(xiàng)目中使用 CancelToken 中止請求

          umi 項(xiàng)目中默認(rèn)的請求庫是umi-request,因此我們可以使用umi-request提供的方法來中止請求。另外,在umi項(xiàng)目中可以搭配使用了dva,因此下面簡單介紹下在dva中使用CancelToken中止請求的流程。

          1、在 services 目錄下的文件中編寫請求函數(shù)和取消請求的函數(shù)

          import?request?from?'@/utils/request';
          const?CancelToken?=?request.CancelToken;
          let?cancel:?any;

          //?合同文件上傳?OSS
          export?async?function?uploadContractFileToOSS(postBody:?Blob):?Promise?{
          ??return?request(`/fms/ossUpload/financial_sys/contractFile`,?{
          ????method:?"POST",
          ????data:?postBody,
          ????requestType:?'form',
          ????//?傳遞一個?executor?函數(shù)到?CancelToken?的構(gòu)造函數(shù)來創(chuàng)建一個?cancel?token
          ????cancelToken:?new?CancelToken((c)?=>?{
          ??????cancel?=?c
          ????})
          ??})
          }

          //?取消合同文件上傳
          export?async?function?cancelUploadFile()?{
          ??return?cancel?&&?cancel()
          }
          復(fù)制代碼

          2、在 models 中編寫 Effect:

          *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ù)制代碼

          3、在頁面中通過dispatch函數(shù)觸發(fā)相應(yīng)的action:

          //?發(fā)起請求
          dispatch({
          ??type:?'contract/fetchContractFiles',
          ??payload:?{
          ????contractId:?`${id}`,
          ??}
          })

          //?取消請求
          dispatch({
          ??type:?"contract/cancelUploadFile"
          })
          ???
          復(fù)制代碼

          4、在 utils/request.js 中統(tǒng)一處理中止請求的攔截:

          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:?`請求錯誤?${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:?'未知錯誤',
          ????});
          ??}
          ??return?response;
          };
          復(fù)制代碼

          關(guān)于本文

          作者:紫圣

          https://juejin.cn/post/7033906910583586829

          最后

          歡迎關(guān)注【前端瓶子君】??ヽ(°▽°)ノ?
          回復(fù)「算法」,加入前端編程源碼算法群,每日一道面試題(工作日),第二天瓶子君都會很認(rèn)真的解答喲!
          回復(fù)「交流」,吹吹水、聊聊技術(shù)、吐吐槽!
          回復(fù)「閱讀」,每日刷刷高質(zhì)量好文!
          如果這篇文章對你有幫助,在看」是最大的支持
          ?》》面試官也在看的算法資料《《
          “在看和轉(zhuǎn)發(fā)”就是最大的支持
          瀏覽 52
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品一二三 | 学生妹内射视频 | 免费xx视频 | 偷窥盗摄国产一区 | 久草福利在线 |