JavaScript中断请求几种方案详解

更新时间:2023-05-23 09:02:13 阅读: 评论:0

JavaScript中断请求⼏种⽅案详解
⽬录
1 Promi
中断调⽤链
汉语翻译英文
中断Promi
包装abort⽅法——仿照Axios的CancelToken
2 RXJS的unsubscribe⽅法
3 Axios的CancelToken
1 Promi
Promi有⼀个缺点是⼀旦创建⽆法取消,所以本质上Promi是⽆法被终⽌的.
但是我们可以通过中断调⽤链或中断Promi来模拟请求的中断.
中断调⽤链
中断调⽤链就是在某⼀个then/catch执⾏之后,后续的链式调⽤(包括then,catch,finally)不再继续执⾏.
⽅法是在then/catch返回⼀个新的Promi实例,并保持pending状态:
new Promi((resolve, reject) => {
tTimeout(() => {
resolve('result');
});
}).then(res => {
// 达到某种条件,return⼀个pending状态的Promi实例,以中断调⽤链
if (res === 'result') {
return new Promi(() => {});
}
console.log(res); // 不打印
}).then(() => {
console.log('then不执⾏'); // 不打印
}).catch(() => {
console.log('catch不执⾏'); // 不打印48个音标发音视频
}).finally(() => {
console.log('finally不执⾏'); // 不打印
});
中断Promi
中断Promi不等同于中⽌Promi,因为Promi是⽆法被终⽌的.
这⾥的中断指的是,在合适的时机,把pending状态的promi给reject掉.例如⼀个常见的应⽤场景就是给⽹络请求设置超时时间,⼀旦超时就中断.
⽼规矩,⽤tTimeout来模拟⽹络请求.阀值设置为Math.random() * 3000表⽰随机3秒之内返回结果.
const request = new Promi((resolve, reject) => {
tTimeout(() => {
resolve('收到服务端数据')
}, Math.random() * 3000)
})
小学生英文作文假设超过2秒就是⽹络超时,我们可以封装⼀个超时处理函数.
由于⽹络请求所需的事件是随机的,因此可以利⽤Promi.race⽅法,达到超时reject的⽬的.
reboot system now什么意思const timeoutReject = (p1, timeout = 2000) => {
const p2 = new Promi((resolve, reject) => {
tTimeout(() => {
reject('⽹络超时');
}, timeout);
});
return Promi.race([p1, p2]);
};
timeoutReject(request).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
});
包装abort⽅法——仿照Axios的CancelToken
上⾯实现的⽅式并不灵活,因为中断Promi的⽅式有很多,不单单是⽹络超时.
我们可以仿照Axios中CancelToken的核⼼源码,简单包装⼀个abort⽅法,供使⽤者随时调⽤.
function abortWrapper(p1) {
let abort;
const p2 = new Promi((resolve, reject) => {
abort = reject;
});
// 如果没有resolve或reject,p2的状态永远是pending
const p = Promi.race([p1, p2]);
p.abort = abort;
return p;
}
const req = abortWrapper(request);
req.then(res => {instincts
console.log(res);
}).catch(err => {
console.log(err);
});
tTimeout(() => {雅思听力机经
// ⼿动调⽤req.abort,将p2的状态改变为rejected
req.abort('⼿动中断请求');
}, 2000);
如此封装的主要⽬的就是为了能够在Promi外部控制其resolve或reject,让使⽤者可以随时⼿动调⽤resolve(触发.then)或reject(触发.catch).
需要注意的是,虽然Promi请求被中断了,但是promi并没有终⽌,⽹络请求依然可能返回,只不过那时我们已经不关⼼请求结果了.
2 RXJS的unsubscribe⽅法
rxjs本⾝提供了取消订阅的⽅法,即unsubscribe.
let stream1$ = new Obrvable(obrver => {
let timeout = tTimeout(() => {
裙子英文('obrvable timeout');
}, 2000);
return () => {
最新大学排名clearTimeout(timeout);
}
});
let disposable = stream1$.subscribe(value => console.log(value));
tTimeout(() => {
disposable.unsubscribe();
}, 1000);
3 Axios的CancelToken
Axios的CancelToken有两种使⽤⽅法:
⽅法⼀
import axios from 'axios';
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
<('/ur/12345', {
cancelToken: ken
}).catch(function (thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', ssage);
} el {
// handle error
}
});
source.cancel('Operation canceled by the ur.');
⽅法⼆
import axios from 'axios';
const CancelToken = axios.CancelToken;
// 创建⼀个变量如 cancel ⽤于存储这个中断某个请求的⽅法
let cancel;
<('/ur/12345', {
cancelToken: new CancelToken(function executor(c) {
cancel = c; // 将参数 c 赋值给 cancel
})
});
/
/ 判断 cancel 是否为函数,确保 axios 已实例化⼀个CancelToken
if (typeof cancel === 'function') {
cancel();
cancel = null;
}
CancelToken的核⼼源码:(axios/lib/cancel/CancelToken.js)
'u strict';
var Cancel = require('./Cancel');
/**
* A `CancelToken` is an object that can be ud to request cancellation of an operation. *
* @class
* @param {Function} executor The executor function.
*/
function CancelToken(executor) {
if (typeof executor !== 'function') {
throw new TypeError('executor must be a function.');
}
var resolvePromi;
this.promi = new Promi(function promiExecutor(resolve) {
resolvePromi = resolve;
});
kingjvar token = this;
executor(function cancel(message) {
if (ason) {
// Cancellation has already been requested
return;
}
ason);
});
}
/**
* Throws a `Cancel` if cancellation has been requested.
*/
mouthwateringCancelToken.prototype.throwIfRequested = function throwIfRequested() {
if (ason) {
ason;
}
};
/**
* Returns an object that contains a new `CancelToken` and a function that, when called, * cancels the `CancelToken`.
*/
CancelToken.source = function source() {
var cancel;
var token = new CancelToken(function executor(c) {
cancel = c;
});
return {
token: token,
cancel: cancel
};
};
可以看到,在Axios底层,CancelToken的核⼼源码所体现的思想,与上⾯中断Promi包装abort⽅法的思想⼀致.
只不过Axios在外部⼿动调⽤resolve(⽤户触发cancel⽅法),⽽resolve⼀旦调⽤,就会触发promi的then⽅法,来看这个promi.then的源码:(axios/lib/adapters/xhr.js)
if (config.cancelToken) {
// Handle cancellation
config.cancelToken.promi.then(function onCanceled(cancel) {
if (!request) {
return;
}
request.abort();
reject(cancel);
// Clean up request
request = null;
});
}
可以看到then⽅法中会执⾏abort⽅法取消请求,同时调⽤reject让外层的promi失败.
到此这篇关于JavaScript 中断请求⼏种⽅案详解的⽂章就介绍到这了,更多相关js中断请求内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!

本文发布于:2023-05-23 09:02:13,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/119358.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:请求   中断   取消   相关   状态
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图