<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ā)出去的請求?

          共 7606字,需瀏覽 16分鐘

           ·

          2022-01-01 18:35


          點(diǎn)擊上方“碼農(nóng)突圍”,馬上關(guān)注

          這里是碼農(nóng)充電第一站,回復(fù)“666”,獲取一份專屬大禮包
          真愛,請?jiān)O(shè)置“星標(biāo)”或點(diǎn)個(gè)“在看
          作者:紫圣
          https://juejin.cn/post/7033906910583586829

          面試官:請求已經(jīng)發(fā)出去了,如何取消掉這個(gè)已經(jīng)發(fā)出去的請求?
          面試者:(腦海里立馬產(chǎn)生一個(gè)疑惑:已經(jīng)發(fā)出去的請求還能取消掉?) 這個(gè)......這個(gè)......還真不知道。
          面試完,馬上找度娘.....
          推薦閱讀:axios解析之cancelToken取消請求原理[2]

          AbortController

          AbortController[3] 接口表示一個(gè)控制器對象,可以根據(jù)需要終止一個(gè)或多個(gè)Web請求。
          • 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 中斷請求

          Fetch 是 Web 提供的一個(gè)用于獲取資源的接口,如果要終止 fetch 請求,則可以使用 Web 提供的 AbortController 接口。
          首先我們使用 AbortController() 構(gòu)造函數(shù)創(chuàng)建一個(gè)控制器,然后使用 AbortController.signal 屬性獲取其關(guān)聯(lián) AbortSignal 對象的引用。當(dāng)一個(gè) fetch request 初始化時(shí),我們把 AbortSignal 作為一個(gè)選項(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 屬性由初始時(shí)的 false 變成了中止后的 true 。
          線上運(yùn)行示例[4] (代碼來源于MDN[5])
          AbortControllter 有兼容性問題,如下:

          axios 中斷請求

          axions 中斷請求有兩種方式:
          方式一
          使用 CancelToken.souce 工廠方法創(chuàng)建一個(gè) 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 {
              // 處理錯(cuò)誤
            }
          });

          // 取消請求(message 參數(shù)是可選的)
          source.cancel('Operation canceled by the user.');
          復(fù)制代碼
          中止后的網(wǎng)絡(luò)請求變成如下所示:
          我們再來看看初始時(shí)和中止后的 souce 狀態(tài):
          可以看到,初始時(shí)和中止后的 source 狀態(tài)并沒還有發(fā)生改變。那么我們是如何判斷請求的中止?fàn)顟B(tài)呢?axios 為我們提供了一個(gè) isCancel() 方法,用于判斷請求的中止?fàn)顟B(tài)。isCancel() 方法的參數(shù),就是我們在中止請求時(shí)自定義的信息。
          方式二
          通過傳遞一個(gè) executor 函數(shù)到 CancelToken 的構(gòu)造函數(shù)來創(chuàng)建一個(gè) cancel token:
          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)行結(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<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ù)制代碼
          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: `請求錯(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ù)【面試題】即可獲取

          瀏覽 45
          點(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>
                  亚洲欧美日韩一区二区 | 无码破解SSIS-726在线 | 丝袜网站 | 97激情| 黑丝空姐在线观看视频 |