当前位置:网站首页>Use of abortcontroller
Use of abortcontroller
2022-06-26 15:26:00 【flytam】
Today I will introduce a useful JavaScript api AbortController
AbortController What is it?
AbortController Interface represents a controller object , Allows you to abort one or more as needed Web request . You can use AbortController.AbortController() Constructor creates a new AbortController. Use AbortSignal Objects can be completed with DOM Requested communication
This api Simply put, it can provide us with the ability to terminate a fetch request
A termination fetch Requested demo as follows :
fetchButton.onclick = async () => {
const controller = new AbortController();
// Click on abort button Implementation termination fetch request
abortButton.onclick = () => controller.abort();
try {
const r = await fetch('/json', {
signal: controller.signal });
const json = await r.json();
} catch (e) {
// If fetch If the request is terminated, an AbortError Error of
const isUserAbort = (e.name === 'AbortError');
}
};

After early termination, this request is made in network In the panel status Is shown as canceled
In the absence of AbortController This api Before , We can't let the browser terminate a request in advance . And with this api after , The browser can terminate the request in advance, thus saving some user bandwidth . besides , This api It can also bring us some new development models
Controller and Signal
The following instantiates a AbortController, its signal Attribute is a AbortSignal
const controller = new AbortController();
const {
signal } = controller;
- controller It can be done by
controller.abort()To terminate its correspondingsignal signalItself cannot be terminated directly . It can be passed to some function calls such as fetch Or directly monitorsignalThe state of change ( Can passsignal.abortedseesignalThe state of or monitoring itabortevent )
The actual use
Termination in normal objects
Some old DOM api It is not supported AbortSignal. for example WebScocket Only one is provided close Method to close when we don't need it . If you want to use AbortSignal Can be similar to the following packaging
function abortableSocket(url, signal) {
const w = new WebSocket(url);
if (signal.aborted) {
w.close(); // signal Close immediately after the termination websocket
}
signal.addEventListener('abort', () => w.close());
return w;
}
This is also very simple to use , But it's important to note that if signal If it has been terminated, it will not trigger abort event , We need to make a judgment first signal Has terminated
Remove event monitoring
We often need to be in js In dealing with dom Monitoring and unloading of . However, the following example will not take effect when the event listening and unloading incoming functions are not the same reference
window.addEventListener('resize', () => doSomething());
// Will not enter into force
window.removeEventListener('resize', () => doSomething());
Therefore, we often need some additional code to maintain the consistency of the callback function reference . And with AbortSignal Then we can have a new way to realize
const controller = new AbortController();
const {
signal } = controller;
window.addEventListener('resize', () => doSomething(), {
signal });
controller.abort();
because addEventListener Can also receive signal Attribute . We only need to call controller.abort(), This controller Of signal The related event listener passed will be unloaded automatically
Constructor mode
stay JavaScript We may need to manage very complex lifecycles in objects , Such as WebSocket. We need to start and then execute a series of logic and then terminate . Maybe we will write the following code
const someObject = new SomeObject();
someObject.start();
// After performing some operations
someObject.stop();
It can also be done through AbortSignal To implement
const controller = new AbortController();
const {
signal } = controller;
const someObject = new someObject(signal);
// After performing some operations
controller.abort();
This makes it very clear that this object can only be executed once , Only from the beginning to the end , But not vice versa . If you want to use it again after it is terminated, you need to create an object again
You can share one in many places
signal. We don't need to hold multipleSomeObjectExample . Just callcontroller.abort(), theseSomeObjectAll instances of can be terminatedIf
SomeObjectThere are also internal calls likefetchAnd so on api Just put thissignalKeep delivering , befetchCan also be terminated together
Here is an example . Shows two signal Usage of . Pass to built-in apifetch And inspection signal State to perform some actions
export class SomeObject {
constructor(signal) {
this.signal = signal;
// Perform some operations, such as sending a request
const p = fetch('/json', {
signal });
}
doComplexOperation() {
if (this.signal.aborted) {
throw new Error(`thing stopped`);
}
for (let i = 0; i < 1_000_000; ++i) {
// Perform complex operations
}
}
}
react hook Asynchronous calls in
We usually go to useEffect Some asynchronism in api call . With the help of signal Next time useEffect Call again api Will terminate the previous call
function FooComponent({
something }) {
useEffect(() => {
const controller = new AbortController();
const {
signal } = controller;
const p = (async () => {
const j = await fetch(url + something, {
signal });
})();
return () => controller.abort();
}, [something]);
return <>...<>;
}
You can also encapsulate a useEffectAsync Of hook
function useEffectAsync(cb,dependence) {
const controller = new AbortController();
const {
signal } = controller;
useEffect(() => {
cb(signal);
return () => controller.abort();
},dependence)
}
Some useful AbortSignal Method
These methods may not be implemented yet
AbortSignal.timeout(ms): Create a that terminates after a given timeAbortSignal
function abortTimeout(ms) {
const controller = new AbortController();
setTimeout(() => controller.abort(), ms);
return controller.signal;
}
AbortSignal.any(signals): Create aAbortSignal, If any of the incomingsignalIt's over , This one returnssignalIt will also be terminated
function abortAny(signals) {
const controller = new AbortController();
signals.forEach((signal) => {
if (signal.aborted) {
controller.abort();
} else {
signal.addEventListener('abort', () => controller.abort());
}
});
return controller.signal;
}
AbortSignal.throwIfAborted(): IfsignalItself has ended , Calling this method will throw an executionabort(reason)When the specified reason abnormal ; Otherwise, it will be executed silently
if (signal.aborted) {
throw new Error(...);
}
// becomes
signal.throwIfAborted();
This method is not easy at present polyfill, But it can be realized through the following tool functions
function throwIfSignalAborted(signal) {
if (signal.aborted) {
throw new Error(...);
}
}
Reference resources
https://whistlr.info/2022/abortcontroller-is-your-friend/
边栏推荐
- /etc/profile、/etc/bashrc、~/. Bashrc differences
- Unity C# 网络学习(九)——WWWFrom
- PHP file upload 00 truncation
- Principle of TCP reset attack
- Program analysis and Optimization - 8 register allocation
- Pod scheduling of kubernetes
- 2Gcsv文件打不开怎么处理,使用byzer工具
- 【毕业季·进击的技术er】 什么是微信小程序,带你推开小程序的大门
- 【ceph】CephFS 内部实现(四):MDS是如何启动的?--未消化
- BLE抓包调试信息分析
猜你喜欢

评价——TOPSIS

Restcloud ETL extracting dynamic library table data
![[tcapulusdb knowledge base] tcapulusdb doc acceptance - create business introduction](/img/05/8ec56393cac534cb5a00c10a1a9f32.png)
[tcapulusdb knowledge base] tcapulusdb doc acceptance - create business introduction
![[tcapulusdb knowledge base] tcapulusdb doc acceptance - transaction execution introduction](/img/7c/25a88f46e02cebd2e003b9590b9c13.png)
[tcapulusdb knowledge base] tcapulusdb doc acceptance - transaction execution introduction

Lexin AWS IOT expresslink module achieves universal availability

数据库-视图
![[tcapulusdb knowledge base] Introduction to tcapulusdb data structure](/img/64/4d7ec393d8469cdadc89078a8cf4b1.png)
[tcapulusdb knowledge base] Introduction to tcapulusdb data structure

Using restcloud ETL shell component to schedule dataX offline tasks

【ceph】CEPHFS 内部实现(一):概念篇--未消化

High frequency interview 𞓜 Flink Shuangliu join
随机推荐
sqlite加载csv文件,并做数据分析
安全Json协议
Unity C# 网络学习(十)——UnityWebRequest(一)
1. accounting basis -- several major elements of accounting (general accounting theory, accounting subjects and accounts)
Redis cluster
Pod scheduling of kubernetes
评价——TOPSIS
Unity C # e-learning (10) -- unitywebrequest (1)
ETL过程中数据精度不准确问题
[wechat applet] event binding, do you understand?
【ceph】cephfs caps简介
【微信小程序】事件绑定,你搞懂了吗?
/etc/profile、/etc/bashrc、~/. Bashrc differences
北京房山区专精特新小巨人企业认定条件,补贴50万
R language uses ggplot2 to visualize the results of Poisson regression model and count results under different parameter combinations
编译配置in文件
High frequency interview 𞓜 Flink Shuangliu join
Is it safe for flush to register and open an account? Is there any risk?
[tcapulusdb knowledge base] tcapulusdb doc acceptance - Introduction to creating game area
小程序:uniapp解决 vendor.js 体积过大的问题