Skip to content

Instantly share code, notes, and snippets.

@zaaack
Created May 17, 2022 08:39
Show Gist options
  • Save zaaack/8fa375730132b60700a05c53e790b603 to your computer and use it in GitHub Desktop.
Save zaaack/8fa375730132b60700a05c53e790b603 to your computer and use it in GitHub Desktop.
common batch fetcher
import axios, { AxiosRequestConfig } from 'axios'
export interface Props<P, Data, D> {
url: string
baseParams?: object
aggregateParams: (p1: P, p2: P) => P
selectData: (d: Data, p: P) => D
waitMs?: number
config?: AxiosRequestConfig
}
export class BatchFetcher<P extends object, Data, D> {
constructor(private config: Props<P, Data, D>) {}
private _fetchTimer?: NodeJS.Timeout
private _resolvers: [P, (value: D | PromiseLike<D>) => void, (err: Error) => void][] = []
async fetch(params: P): Promise<D> {
return new Promise((resolve, reject) => {
this._resolvers.push([params, resolve, reject])
this._fetchTimer && clearTimeout(this._fetchTimer)
this._fetchTimer = setTimeout(() => {
axios
.get<Data>(this.config.url, {
params: {
...this.config.baseParams,
...params,
},
})
.then((r) => {
this._resolvers.forEach(([p, res, rej]) => {
try {
let d = this.config.selectData(r.data, p)
res(d)
} catch (error) {
console.error(error)
rej(error)
}
})
this._resolvers = []
})
.catch((err) => {
this._resolvers.forEach(([p, res, rej]) => {
rej(err)
})
this._resolvers = []
})
}, this.config.waitMs || 1)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment