The encapsulation of fetch
/XMLHttpRequest
/axios
makes it possible to use scopes to identify requests, and to
cancel requests under a certain (several) scopes. Request/Response interceptors are also supported.
UseAxios
axios
as peerDependencynode >= v15.0.0
to supportAbortController
UseFetch
node >= v17.5.0
to supportfetch api
This is a general generic function used by other classes. When the promise fails, it will automatically repeat several times and then throw the error. Expose here to enable retrying of custom behavior.
- declaration
declare const do_retry_task: <Params extends Array<any> = any[], Response = any>
(max: number,
task: (...args: Params) => Promise<Response>,
args: Params,
immediate_condition?: ((err: any) => boolean) | undefined)
=> Promise<Response>;
- example
import { do_retry_task } from "better-xhr";
let count = 0
const countup_in_1s = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
count += 1
console.log('now count is: ', count)
reject('for auto retry')
}, 1_000)
})
}
do_retry_task(5, countup_in_1s, [])
.then(res => {
console.log('res: ', res)
})
.catch(err => {
console.log('err: ', err)
})
// now count is: 1 - origin request
// now count is: 2 - retry 1
// now count is: 3 - retry 2
// now count is: 4 - retry 3
// now count is: 5 - retry 4
// now count is: 6 - retry 5
// err: for auto retry - promise after auto-retry
axios
as peerDependencynode >= v15.0.0
to supportAbortController
GET
import { UseAxios } from "better-xhr";
const useAxios = new UseAxios();
// single request
useAxios
.get(
'scope-name',
'target-url',
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useAxios
.get_retry(
'scope-name', 5,
'target-url',
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
POST
import { UseAxios } from "better-xhr";
const useAxios = new UseAxios();
// single request
useAxios
.post(
'scope-name',
'target-url',
null, // post data in any type
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useAxios
.post(
'scope-name', 5,
'target-url',
null, // post data in any type
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
DELETE
import { UseAxios } from "better-xhr";
const useAxios = new UseAxios();
// single request
useAxios
.delete(
'scope-name',
'target-url',
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useAxios
.delete_retry(
'scope-name', 5,
'target-url',
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
PUT
import { UseAxios } from "better-xhr";
const useAxios = new UseAxios();
// single request
useAxios
.put(
'scope-name',
'target-url',
null, // put data in any type
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useAxios
.put_retry(
'scope-name', 5,
'target-url',
null, // put data in any type
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
HEAD
import { UseAxios } from "better-xhr";
const useAxios = new UseAxios();
// single request
useAxios
.head(
'scope-name',
'target-url',
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useAxios
.head_retry(
'scope-name', 5,
'target-url',
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
OPTIONS
import { UseAxios } from "better-xhr";
const useAxios = new UseAxios();
// single request
useAxios
.options(
'scope-name',
'target-url',
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useAxios
.options_retry(
'scope-name', 5,
'target-url',
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
PATCH
import { UseAxios } from "better-xhr";
const useAxios = new UseAxios();
// single request
useAxios
.patch(
'scope-name',
'target-url',
null, // put data in any type
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useAxios
.patch_retry(
'scope-name', 5,
'target-url',
null, // put data in any type
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
Scope
&Cancel
import { UseAxios } from "better-xhr";
const useAxios = new UseAxios();
// setup a request with scope
useAxios
.get(
'scope-name',
'target-url',
{} // optional config for axios
)
.then(res => {
console.log(res)
})
.catch(err => {
const if_manually_cancel = useAxios.isCancel(err)
console.log(if_manually_cancel
? 'the request is cancelled by code!'
: 'error occurred when request!')
})
// get all scopes in the instance
const scopes = useAxios.scopes
console.log(scopes) // [ 'scope-name' ]
// cancel specific scope
useAxios.cancel_scope('scope-name')
// cancel scopes
useAxios.cancel_scopes([ 'scope1', 'scope2', 'scope3' ])
// cancel all request
useAxios.cancel_all()
Interceptor
import { UseAxios } from "better-xhr";
const useAxios = new UseAxios();
// request interceptor
// - add
useAxios
.add_request_interceptor(
'interceptor1',
(config) => {
/** operate config here */
}
)
// - list
console.log(useAxios.request_interceptors) // [ 'interceptor1' ]
// - remove
useAxios.remove_request_interceptor('interceptor1')
// response interceptor
// - add
useAxios
.add_response_interceptor(
'interceptor2',
{
fulfill: (res) => {
/** operate response */
},
reject: (err) => {
/** operate error */
}
}
)
// - list
console.log(useAxios.response_interceptors) // [ 'interceptor2' ]
// - remove
useAxios.remove_response_interceptor('interceptor2')
node >= v17.5.0
to supportfetch api
GET
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// single request
useFetch
.get(
'scope-name',
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useFetch
.get_retry(
'scope-name', 5,
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
POST
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// single request
useFetch
.post(
'scope-name',
'target-url',
{
body: null // post data in any type
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useFetch
.post_retry(
'scope-name', 5,
'target-url',
{
body: null // post data in any type
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
DELETE
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// single request
useFetch
.delete(
'scope-name',
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useFetch
.delete_retry(
'scope-name', 5,
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
PUT
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// single request
useFetch
.put(
'scope-name',
'target-url',
{
body: null // put data in any type
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useFetch
.put_retry(
'scope-name', 5,
'target-url',
{
body: null // put data in any type
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
HEAD
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// single request
useFetch
.head(
'scope-name',
'target-url',
{
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useFetch
.put_retry(
'scope-name', 5,
'target-url',
{
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
CONNECT
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// single request
useFetch
.connect(
'scope-name',
'target-url',
{
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useFetch
.connect_retry(
'scope-name', 5,
'target-url',
{
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
OPTIONS
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// single request
useFetch
.options(
'scope-name',
'target-url',
{
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useFetch
.options_retry(
'scope-name', 5,
'target-url',
{
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
TRACE
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// single request
useFetch
.trace(
'scope-name',
'target-url',
{
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useFetch
.trace_retry(
'scope-name', 5,
'target-url',
{
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
PATCH
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// single request
useFetch
.patch(
'scope-name',
'target-url',
{
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useFetch
.patch_retry(
'scope-name', 5,
'target-url',
{
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
Scope
&Cancel
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// setup a request with scope
useFetch
.get(
'scope-name',
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// get all scopes in the instance
const scopes = useFetch.scopes
console.log(scopes) // [ 'scope-name' ]
// cancel specific scope
useFetch.cancel_scope('scope-name')
// cancel scopes
useFetch.cancel_scopes([ 'scope1', 'scope2', 'scope3' ])
// cancel all request
useFetch.cancel_all()
Interceptor
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// request interceptor
// - add
useFetch
.add_request_interceptor(
'interceptor1',
(config) => {
/** operate config here */
}
)
// - list
console.log(useFetch.request_interceptors) // [ 'interceptor1' ]
// - remove
useFetch.remove_request_interceptor('interceptor1')
// response interceptor
// - add
useFetch
.add_response_interceptor(
'interceptor2',
{
fulfill: (res) => {
/** operate response */
},
reject: (err) => {
/** operate error */
}
}
)
// - list
console.log(useFetch.response_interceptors) // [ 'interceptor2' ]
// - remove
useFetch.remove_response_interceptor('interceptor2')
GET
import { UseXhr } from "better-xhr";
const useXhr = new UseXhr();
// single request
useXhr
.get(
'scope-name',
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useXhr
.get_retry(
'scope-name', 5,
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
POST
import { UseXhr } from "better-xhr";
const useXhr = new UseXhr();
// single request
useXhr
.post(
'scope-name',
'target-url',
{
body: null // request body
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useXhr
.post_retry(
'scope-name', 5,
'target-url',
{
body: null // request body
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
DELETE
import { UseXhr } from "better-xhr";
const useXhr = new UseXhr();
// single request
useXhr
.delete(
'scope-name',
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useXhr
.delete_retry(
'scope-name', 5,
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
PUT
import { UseXhr } from "better-xhr";
const useXhr = new UseXhr();
// single request
useXhr
.put(
'scope-name',
'target-url',
{
body: null // request body
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useXhr
.put_retry(
'scope-name', 5,
'target-url',
{
body: null // request body
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
HEAD
import { UseXhr } from "better-xhr";
const useXhr = new UseXhr();
// single request
useXhr
.head(
'scope-name',
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useXhr
.head_retry(
'scope-name', 5,
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
CONNECT
import { UseXhr } from "better-xhr";
const useXhr = new UseXhr();
// single request
useXhr
.connect(
'scope-name',
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useXhr
.connect_retry(
'scope-name', 5,
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
OPTIONS
import { UseXhr } from "better-xhr";
const useXhr = new UseXhr();
// single request
useXhr
.options(
'scope-name',
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useXhr
.options_retry(
'scope-name', 5,
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
TRACE
import { UseXhr } from "better-xhr";
const useXhr = new UseXhr();
// single request
useXhr
.trace(
'scope-name',
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useXhr
.trace_retry(
'scope-name', 5,
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
PATCH
import { UseXhr } from "better-xhr";
const useXhr = new UseXhr();
// single request
useXhr
.patch(
'scope-name',
'target-url',
{
body: null // request body
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// auto retry
useXhr
.patch_retry(
'scope-name', 5,
'target-url',
{
body: null // request body
// optional config for fetch
}
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
Scope
&Cancel
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// setup a request with scope
useFetch
.get(
'scope-name',
'target-url',
{} // optional config for fetch
)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// get all scopes in the instance
const scopes = useFetch.scopes
console.log(scopes) // [ 'scope-name' ]
// cancel specific scope
useFetch.cancel_scope('scope-name')
// cancel scopes
useFetch.cancel_scopes([ 'scope1', 'scope2', 'scope3' ])
// cancel all request
useFetch.cancel_all()
Interceptor
import { UseFetch } from "better-xhr";
const useFetch = new UseFetch();
// request interceptor
// - add
useFetch
.add_request_interceptor(
'interceptor1',
(config) => {
/** operate config here */
}
)
// - list
console.log(useFetch.request_interceptors) // [ 'interceptor1' ]
// - remove
useFetch.remove_request_interceptor('interceptor1')
// response interceptor
// - add
useFetch
.add_response_interceptor(
'interceptor2',
{
fulfill: (res) => {
/** operate response */
},
reject: (err) => {
/** operate error */
}
}
)
// - list
console.log(useFetch.response_interceptors) // [ 'interceptor2' ]
// - remove
useFetch.remove_response_interceptor('interceptor2')