JS如何為promise增加abort功能
概述
Promise只有三種狀態(tài):pending、resolve、reject,一個異步的承諾一旦發(fā)出,經(jīng)歷等待(pending)后,最終只能為成功或者失敗,中途無法取消(abort)。
為promise提供abort功能的思路有兩種:
- 手動實現(xiàn)abort,觸發(fā)取消后,異步回來的數(shù)據(jù)直接丟棄(手動實現(xiàn),比較穩(wěn)妥)
- 使用原生方法AbortController中斷請求(實驗中的方法,有兼容性,ie不支持)
手動實現(xiàn)abort方法有兩種模式:都是依賴promise的接口間接實現(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
(這是一個實驗中的功能,歸屬于DOM規(guī)范,此功能某些瀏覽器尚在開發(fā)中)AbortController接口代表一個控制器對象,允許你在需要時中止一個或多個DOM請求。
// 中斷fetch請求
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.
//中斷一個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的請求可以一并取消
在現(xiàn)在項目中使用最頻繁的是axios,所以取消請求不用擔心。dom規(guī)范的AbortController,由于兼容性,不推薦使用。如果需要自己動手實現(xiàn)的話,還是文章前兩種方法較穩(wěn)妥(promise race方法和重新包裝promise方法)。
以上就是JS為promise增加abort功能的詳細內(nèi)容,更多關(guān)于JS的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
DB.ASP 用Javascript寫ASP很靈活很好用很easy
DB.ASP 用Javascript寫ASP很靈活很好用很easy,喜歡用js寫asp的朋友可以參考下。2011-07-07
JavaScript模仿Pinterest實現(xiàn)圖片預加載功能
圖片預加載是web開發(fā)中一種應用相當廣泛的技術(shù),比如我們在做圖片翻轉(zhuǎn)顯示等特效的時候,為了讓圖片在轉(zhuǎn)換的時候不出現(xiàn)等待,我們最好是先讓圖片下載到本地,然后在繼續(xù)執(zhí)行后續(xù)的操作。今天本文主要介紹的是利用JS模仿Pinterest圖片社交網(wǎng)站的圖片預加載功能。2016-10-10
JavaScript中“過于”犀利地for/in循環(huán)使用示例
Java中的增強for循環(huán)很是好用,但是JavaScript中為我們提供的for/in循環(huán)已然不是這么簡單了,下面有個簡單的示例,大家不妨參考下2013-10-10
javascript中數(shù)組(Array)對象和字符串(String)對象的常用方法總結(jié)
這篇文章主要介紹了javascript中數(shù)組(Array)對象和字符串(String)對象的常用方法,結(jié)合實例形式總結(jié)分析了javascript中關(guān)于數(shù)組和字符串的常用函數(shù)與使用技巧,需要的朋友可以參考下2016-12-12
JavaScript實現(xiàn)頁面跳轉(zhuǎn)的八種方式
這篇文章介紹了JavaScript實現(xiàn)頁面跳轉(zhuǎn)的八種方式,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06

