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

前端取消接口調(diào)用的方法示例

 更新時(shí)間:2025年03月04日 09:29:56   投稿:daisy  
這篇文章主要介紹了前端取消接口調(diào)用的相關(guān)資料,講解了XMLHttpRequest和AbortController兩種取消HTTP請(qǐng)求的方法,XMLHttpRequest通過(guò)abort()方法取消請(qǐng)求,而AbortController提供了一個(gè)更現(xiàn)代和靈活的解決方案,需要的朋友可以參考下

1. xmlHttpRequest是如何取消請(qǐng)求的?

實(shí)例化的XMLHttpRequest對(duì)象上也有abort方法

const xhr = new XMLHttpRequest();
xhr.addEventListener('load', function(e) {
  console.log(this.responseText);
});
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');
xhr.send();

// 返回
{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

如果在send后直接abort取消

// xhr的取消操作:執(zhí)行過(guò)程比較模糊,不知道abort什么時(shí)機(jī)進(jìn)行處理
xhr.abort()

如果在定時(shí)器中(當(dāng)定時(shí)器的時(shí)長(zhǎng)那個(gè)和接口請(qǐng)求時(shí)長(zhǎng)差不多)取消請(qǐng)求,會(huì)發(fā)現(xiàn)資源已經(jīng)獲取到了,但是控制臺(tái)沒(méi)有打印

2. AbortController

const ac = new AbortController();
const { signal } = ac;
const url = "https://jsonplaceholder.typicode.com/todos/1";
?
fetch(url, { signal })
  .then((res) => res.json())
  .then((json) => console.log(json));

直接使用abort取消請(qǐng)求

ac.abort()

這里報(bào)錯(cuò)的原因是沒(méi)有對(duì)錯(cuò)誤進(jìn)行捕獲

// 修改后的代碼
fetch(url, { signal: ac.signal })
  .then((res) => res.json())
  .then((json) => console.log(json))
  .catch(e => console.log(e)) // DOMException: signal is aborted without reason
ac.abort() // abort接受一個(gè)入?yún)ⅲ瑫?huì)被傳遞到signal的reason屬性中

為什么可以這樣取消?

fetch監(jiān)聽(tīng)signal對(duì)象的狀態(tài),進(jìn)而可以終止請(qǐng)求

2.1 如何同時(shí)取消多個(gè)請(qǐng)求?

const ac = new AbortController();
const { signal } = ac;
const url = "https://jsonplaceholder.typicode.com/todos";
?
const todoRequest = (id, { signal }) => {
  fetch(`${url}/${id}`, { signal })
    .then((res) => res.json())
    .then((json) => console.log(json))
    .catch((e) => console.log(e)); // DOMException: signal is aborted without reason
};
?
todoRequest(1, { signal });
todoRequest(2, { signal });
todoRequest(3, { signal });
?
ac.abort("cancled");

2.2 AbortSignal

是一個(gè)接口,用于表示一個(gè)信號(hào)對(duì)象,它允許你與正在執(zhí)行的異步操作通信,以便可以在操作完成之前將其中止。

2.3 AbortSignal的方法

2.3.1 abort

靜態(tài)方法,用于創(chuàng)建一個(gè)已經(jīng)中止的 AbortSignal 對(duì)象。當(dāng)你調(diào)用這個(gè)方法時(shí),它會(huì)返回一個(gè)帶有 aborted 狀態(tài)為 true 的 AbortSignal 實(shí)例。

const signalAbout = AbortSignal.abort(); // AbortSignal {aborted: true, reason: DOMException: signal is aborted without reason...}

2.3.2 throwIfAborted 方法

用于在執(zhí)行代碼之前檢查 AbortSignal 是否已經(jīng)被中止。如果 AbortSignal 已經(jīng)被中止,它會(huì)拋出一個(gè) AbortError。這個(gè)方法可以幫助開(kāi)發(fā)者在執(zhí)行特定操作之前確保沒(méi)有被中止,以避免不必要的處理。

const signalAbout = AbortSignal.abort('abortedReason');
try {
    signalAbout.throwIfAborted(); // 拋出error: abortedReason
} catch (error) {
    console.log(error);
}

2.3.3 timeout

用于創(chuàng)建一個(gè)在指定時(shí)間后自動(dòng)中止的 AbortSignal 對(duì)象。這在需要設(shè)置請(qǐng)求超時(shí)時(shí)非常有用。

// 使用 AbortSignal.timeout 設(shè)置 10ms超時(shí)
const signalAbout = AbortSignal.timeout(10);
const todoRequest = (id, { signal }) => {
  fetch(`${url}/${id}`, { signal })
    .then((res) => res.json())
    .then((json) => console.log("json: ", json))
    .catch((e) => console.log("err: ", e)); //DOMException: signal timed out 
};
todoRequest(1, { signal: signalAbout });

2.3.3.1 添加事件監(jiān)聽(tīng) => 從沒(méi)有終止到被終止

AbortSignal繼承自EventTarget,因?yàn)?AbortSignal 是用來(lái)監(jiān)聽(tīng) abort 事件的,而 EventTarget 提供了添加、移除和觸發(fā)事件監(jiān)聽(tīng)器的機(jī)制。

const signalAbout = AbortSignal.timeout(10);
signalAbout.addEventListener("abort", (e) => {
    console.log("aborted: ", e);
})?

e的打印如下:

3. 實(shí)現(xiàn)一個(gè)主動(dòng)取消的promise

const ac = new AbortController();
const { signal } = ac;
?
const cancelablePromise = ({signal}) => 
    new Promise((resolve, reject) => {
        // 情況1:直接主動(dòng)取消
        signal?.throwIfAborted(); // 也可以用reject
?
        // 情況2:正常處理業(yè)務(wù)邏輯
?
        setTimeout(() => {
            Math.random() > 0.5 ? resolve('data') : reject('fetch error');
        }, 1000);
?
        // 情況3:超時(shí) todo?
?
        // 監(jiān)聽(tīng)取消
        signal.addEventListener("abort", () => {
            reject(signal?.reason);
        });
    })
// 發(fā)起網(wǎng)絡(luò)請(qǐng)求
cancelablePromise({signal})
.then(res => console.log('res: ', res))
.catch(err => console.log('err: ', err))
// 情況1 
// ac.abort('用戶離開(kāi)頁(yè)面了') // err:  用戶離開(kāi)頁(yè)面了
?
// 情況2 正常請(qǐng)求 err:  fetch error || res:  data

4. 如何使用signal取消事件監(jiān)聽(tīng)?

當(dāng)對(duì)一個(gè)元素添加了多個(gè)事件監(jiān)聽(tīng),不需要像removeEventListener一樣,每個(gè)事件都需要取消一次,每次都要寫(xiě)明對(duì)應(yīng)事件的事件句柄

使用signal 只需要取消一次信號(hào),全部事件監(jiān)聽(tīng)都被取消

const ac = new AbortController();
const { signal } = ac;
const eleA = document.querySelector('#a');
const eleB = document.querySelector('#b');
?
function aEleHandler () {}; // 事件
eleA.addEventListener('click', aEleHandler, {signal}); // 無(wú)論綁定多少個(gè)事件,都只需要一個(gè)signal
?
eleB.addEventListener('click', () => {
    ac.abort(); // 只需要取消一次
})

5. 請(qǐng)求多個(gè)接口進(jìn)行數(shù)據(jù)組裝的場(chǎng)景

當(dāng)網(wǎng)速不好的時(shí)候,如何取消這種不斷進(jìn)行的網(wǎng)絡(luò)請(qǐng)求?

const ac = new AbortController();
const { signal } = ac;
const fetchAndRenderAction = (signal) => {
    requestData(signal); // 多個(gè)串行或者并行的接口
    drawAndRender(signal); // 異步渲染
}
?
try{
    fetchAndRenderAction({signal})
}catch{
    // dosomething...
}

6. 總結(jié)

對(duì)于用戶主動(dòng)離開(kāi)頁(yè)面,或者用戶的網(wǎng)絡(luò)很卡的時(shí)候(預(yù)期返回順序是:接口1 => 接口2;但是接口1返回太慢,導(dǎo)致順序混亂。)這就需要手動(dòng)終止請(qǐng)求。構(gòu)造函數(shù)AbortController的實(shí)例信號(hào)量signal(可以作為ref存儲(chǔ)起來(lái)),signal作為fetch的參數(shù),在每次請(qǐng)求的時(shí)候,可以手動(dòng)調(diào)用abort方法,取消上一次的請(qǐng)求。

到此這篇關(guān)于前端取消接口調(diào)用的文章就介紹到這了,更多相關(guān)前端取消接口調(diào)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • QQ郵箱的一個(gè)文本編輯器代碼

    QQ郵箱的一個(gè)文本編輯器代碼

    QQ郵箱的一個(gè)文本編輯器代碼...
    2007-03-03
  • JS原型對(duì)象操作實(shí)例分析

    JS原型對(duì)象操作實(shí)例分析

    這篇文章主要介紹了JS原型對(duì)象操作,結(jié)合實(shí)例形式分析了JS原型對(duì)象基本原理、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-06-06
  • JS中hasOwnProperty方法用法簡(jiǎn)介

    JS中hasOwnProperty方法用法簡(jiǎn)介

    hasOwnProperty(propertyName)方法 是用來(lái)檢測(cè)屬性是否為對(duì)象的自有屬性,如果是,返回true,否者false; 參數(shù)propertyName指要檢測(cè)的屬性名,這篇文章給大家介紹JS中hasOwnProperty方法用法簡(jiǎn)介,感興趣的朋友一起看看吧
    2024-01-01
  • JS實(shí)現(xiàn)超精簡(jiǎn)響應(yīng)鼠標(biāo)顯示二級(jí)菜單代碼

    JS實(shí)現(xiàn)超精簡(jiǎn)響應(yīng)鼠標(biāo)顯示二級(jí)菜單代碼

    這篇文章主要介紹了JS實(shí)現(xiàn)超精簡(jiǎn)響應(yīng)鼠標(biāo)顯示二級(jí)菜單代碼,可實(shí)現(xiàn)針對(duì)鼠標(biāo)事件的響應(yīng)動(dòng)態(tài)修改頁(yè)面元素屬性的功能,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下
    2015-09-09
  • 詳解微信小程序的不同函數(shù)調(diào)用的幾種方法

    詳解微信小程序的不同函數(shù)調(diào)用的幾種方法

    這篇文章主要介紹了微信小程序的不同函數(shù)調(diào)用的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • JavaScript實(shí)現(xiàn)煙花綻放動(dòng)畫(huà)效果

    JavaScript實(shí)現(xiàn)煙花綻放動(dòng)畫(huà)效果

    這篇文章主要介紹了JavaScript如何實(shí)現(xiàn)煙花綻放動(dòng)畫(huà)效果,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-08-08
  • 使用p5.js實(shí)現(xiàn)動(dòng)態(tài)GIF圖片臨摹重現(xiàn)

    使用p5.js實(shí)現(xiàn)動(dòng)態(tài)GIF圖片臨摹重現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了使用p5.js實(shí)現(xiàn)動(dòng)態(tài)GIF圖片臨摹重現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • JavaScript constructor和instanceof,JSOO中的一對(duì)歡喜冤家

    JavaScript constructor和instanceof,JSOO中的一對(duì)歡喜冤家

    現(xiàn)在流行面向?qū)ο?JavaScript當(dāng)然要迎頭趕上. 有說(shuō)法JavaScript就是徹頭徹尾的OO語(yǔ)言,但我覺(jué)得JavaScript實(shí)現(xiàn)面向?qū)ο蟮某绦蜻€是有諸多不便的.
    2009-05-05
  • javascript 關(guān)于賦值、淺拷貝、深拷貝的個(gè)人理解

    javascript 關(guān)于賦值、淺拷貝、深拷貝的個(gè)人理解

    關(guān)于賦值、淺拷貝、深拷貝,以前也思考良久,很多時(shí)候都以為記住了,但是,我太難了。今天我特地寫(xiě)下筆記,希望可以完全掌握這個(gè)東西,也希望可以幫助到任何想對(duì)學(xué)習(xí)這個(gè)東西的同學(xué)
    2019-11-11
  • javascript實(shí)現(xiàn)下拉菜單效果

    javascript實(shí)現(xiàn)下拉菜單效果

    這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)下拉菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-02-02

最新評(píng)論

许昌市| 五常市| 安塞县| 姚安县| 简阳市| 泸定县| 汕头市| 社旗县| 涪陵区| 辰溪县| 宜君县| 清镇市| 茌平县| 崇州市| 乾安县| 札达县| 上饶县| 甘泉县| 吉安县| 且末县| 灌阳县| 鹰潭市| 商南县| 彰武县| 双峰县| 乌鲁木齐市| 莫力| 泸西县| 四子王旗| 吴忠市| 桃源县| 崇明县| 伊川县| 怀来县| 嘉兴市| 赤壁市| 大名县| 汾西县| 黄浦区| 乐陵市| 合作市|