JS如何為promise增加abort功能
Promise只有三種狀態(tài):pending、resolve、reject,一個(gè)異步的承諾一旦發(fā)出,經(jīng)歷等待(pending)后,最終只能為成功或者失敗,中途無(wú)法取消(abort)。
為promise提供abort功能的思路有兩種:
手動(dòng)實(shí)現(xiàn)abort,觸發(fā)取消后,異步回來(lái)的數(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: abortAbortController
(這是一個(gè)實(shí)驗(yàn)中的功能,歸屬于DOM規(guī)范,此功能某些瀏覽器尚在開(kāi)發(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è)promiseclass 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: AbortedAxios插件自帶取消功能
//1.使用source的tokenconst 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. 通過(guò)傳出的functionconst 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 requestcancel();//主要:使用相同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)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. ASP刪除img標(biāo)簽的style屬性只保留src的正則函數(shù)2. xpath簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理3. 解析原生JS getComputedStyle4. 輕松學(xué)習(xí)XML教程5. jsp實(shí)現(xiàn)登錄驗(yàn)證的過(guò)濾器6. jsp+servlet簡(jiǎn)單實(shí)現(xiàn)上傳文件功能(保存目錄改進(jìn))7. ASP常用日期格式化函數(shù) FormatDate()8. css代碼優(yōu)化的12個(gè)技巧9. msxml3.dll 錯(cuò)誤 800c0019 系統(tǒng)錯(cuò)誤:-2146697191解決方法10. jsp EL表達(dá)式詳解
