JS如何為promise增加abort功能
概述
Promise只有三種狀態(tài):pending、resolve、reject,一個(gè)異步的承諾一旦發(fā)出,經(jīng)歷等待(pending)后,最終只能為成功或者失敗,中途無法取消(abort)。
為promise提供abort功能的思路有兩種:
- 手動(dòng)實(shí)現(xiàn)abort,觸發(fā)取消后,異步回來的數(shù)據(jù)直接丟棄(手動(dòng)實(shí)現(xiàn),比較穩(wěn)妥)
- 使用原生方法AbortController中斷請(qǐng)求(實(shí)驗(yàn)中的方法,有兼容性,ie不支持)
手動(dòng)實(shí)現(xiàn)abort方法有兩種模式:都是依賴promise的接口間接實(shí)現(xiàn)
promise race方法
let PromiseWithAbort = function(promise){ let _abort = null; let Pabort = new Promise((res,rej)=>{ _abort = function(reason ='abort !'){ console.warn(reason); rej(reason); } }); let race = Promise.race([promise,Pabort]); race.abort = _abort; console.log(promise,Pabort); return race; } let p1= new Promise(res=>{ setTimeout(()=>{ res('p1 success'); },2000) }) let testP = PromiseWithAbort(p1); testP.then(res=>{ console.log('success:',res); },error=>{ console.log('error:',error); }) testP.abort(); // 結(jié)果: reject: abort!
重新包裝promise
class PromiseWithAbort { constructor(fn){ let _abort = null; let _p = new Promise((res,rej)=>{ fn.call(null,res,rej); _abort = function(error='abort'){ rej(error); } }) _p.abort = _abort; return _p; } } let testP = new PromiseWithAbort((res,rej)=>{ setTimeout(() => { res(1); },1000); }); testP.then(r=>{ console.log('res:',r); },r=>{ console.log('rej:',r); }); testP.abort(); //結(jié)果: rej: abort
AbortController
(這是一個(gè)實(shí)驗(yàn)中的功能,歸屬于DOM規(guī)范,此功能某些瀏覽器尚在開發(fā)中)AbortController接口代表一個(gè)控制器對(duì)象,允許你在需要時(shí)中止一個(gè)或多個(gè)DOM請(qǐng)求。
// 中斷fetch請(qǐng)求 let controller = new AbortController(); let signal = controller.signal; fetch('https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally',{signal}).then(r=>{ console.log(r); }); controller.abort(); //結(jié)果: Uncaught (in promise) DOMException: The user aborted a request. //中斷一個(gè)promise class PromiseWithAbortController { constructor(fn,{signal}){ if(signal && signal.aborted){ return Promise.reject(new DOMException('Aborted','AbortError')); } let _p = new Promise((resolve,reject)=>{ fn.call(null,resolve,reject); if(signal){ signal.addEventListener('abort',()=>{ reject(new DOMException('Aborted','AbortError')); }) } }); return _p; } } let controller = new AbortController(); let signal = controller.signal; let testP2 = new PromiseWithAbortController((r,j)=>{ setTimeout(() => { r('success'); }, 1000); },{signal}); testP2.then(r=>{ console.log('res:',r); },r=>{ console.log('rej:',r); }); controller.abort(); // 結(jié)果: rej: DOMException: Aborted
Axios插件自帶取消功能
//1.使用source的token const CancelToken = axios.CancelToken; const source = CancelToken.source(); axios.get('/user/12345', { cancelToken: source.token }).catch(function (thrown) { if (axios.isCancel(thrown)) { console.log('Request canceled', thrown.message); } else { // handle error } }); axios.post('/user/12345', { name: 'new name' }, { cancelToken: source.token }) // cancel the request (the message parameter is optional) source.cancel('Operation canceled by the user.'); //2. 通過傳出的function const CancelToken = axios.CancelToken; let cancel; axios.get('/user/12345', { cancelToken: new CancelToken(function executor(c) { // An executor function receives a cancel function as a parameter cancel = c; }) }); // cancel the request cancel(); //主要:使用相同token的請(qǐng)求可以一并取消
在現(xiàn)在項(xiàng)目中使用最頻繁的是axios,所以取消請(qǐng)求不用擔(dān)心。dom規(guī)范的AbortController,由于兼容性,不推薦使用。如果需要自己動(dòng)手實(shí)現(xiàn)的話,還是文章前兩種方法較穩(wěn)妥(promise race方法和重新包裝promise方法)。
以上就是JS為promise增加abort功能的詳細(xì)內(nèi)容,更多關(guān)于JS的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于javascript實(shí)現(xiàn)tab切換特效
這篇文章主要介紹了基于javascript實(shí)現(xiàn)tab切換特效的相關(guān)資料,具有一定的參考價(jià)值,需要的朋友可以參考下2016-03-03uniapp組件傳值的方法(父傳子,子傳父,對(duì)象傳值)實(shí)戰(zhàn)案例
現(xiàn)在的前端開發(fā)中基本上都是組件化開發(fā)的,下面這篇文章主要給大家介紹了關(guān)于uniapp組件傳值(父傳子,子傳父,對(duì)象傳值)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03JS中使用TextDecoder解碼二進(jìn)制數(shù)據(jù)(數(shù)據(jù)流的逐步解碼)
JS中使用TextDecoder將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為可讀文本字符串,首先,創(chuàng)建TextDecoder對(duì)象,使用decode()方法,解碼為字符串,,{stream:true}選項(xiàng)允許處理流式數(shù)據(jù),適用于大型數(shù)據(jù)流的逐步解碼,TextDecoder廣泛應(yīng)用于WebSocket通信、文件讀取、網(wǎng)絡(luò)響應(yīng)等場景2024-10-10JS 判斷undefined的實(shí)現(xiàn)代碼
JS中如何判斷undefined2009-11-11TypeScript內(nèi)置工具類型快速入門運(yùn)用
TypeScript 中內(nèi)置了很多工具類型,我們無需導(dǎo)入,可以直接使用。 其中的很多都是比較常用的,接下來我們根據(jù)使用范圍來一一介紹,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-03-03JavaScript實(shí)現(xiàn)返回頂部按鈕案例
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)返回頂部按鈕案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11