ahooks
Version:
react hooks library
121 lines (120 loc) • 4.9 kB
JavaScript
import { __awaiter, __rest } from "tslib";
import { isFunction } from '../../utils';
import { CancelledError, isCancelledError } from './utils/cancelledError';
export default class Fetch {
constructor(serviceRef, options, subscribe, initState = {}) {
this.serviceRef = serviceRef;
this.options = options;
this.subscribe = subscribe;
this.initState = initState;
this.pluginImpls = [];
this.count = 0;
this.state = {
loading: false,
params: undefined,
data: undefined,
error: undefined,
};
this.state = Object.assign(Object.assign(Object.assign({}, this.state), { loading: !options.manual }), initState);
}
setState(s = {}) {
this.state = Object.assign(Object.assign({}, this.state), s);
this.subscribe();
}
runPluginHandler(event, ...rest) {
// @ts-ignore
const r = this.pluginImpls.map((i) => { var _a; return (_a = i[event]) === null || _a === void 0 ? void 0 : _a.call(i, ...rest); }).filter(Boolean);
return Object.assign({}, ...r);
}
runAsync(...params) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
this.count += 1;
const currentCount = this.count;
const _l = this.runPluginHandler('onBefore', params), { stopNow = false, returnNow = false } = _l, state = __rest(_l, ["stopNow", "returnNow"]);
// stop request
if (stopNow) {
return Promise.resolve(state.data);
}
this.setState(Object.assign({ loading: true, params }, state));
// return now
if (returnNow) {
return Promise.resolve(state.data);
}
(_b = (_a = this.options).onBefore) === null || _b === void 0 ? void 0 : _b.call(_a, params);
try {
// replace service
let { servicePromise } = this.runPluginHandler('onRequest', this.serviceRef.current, params);
if (!servicePromise) {
servicePromise = this.serviceRef.current(...params);
}
const res = yield servicePromise;
if (currentCount !== this.count) {
throw new CancelledError();
}
// const formattedResult = this.options.formatResultRef.current ? this.options.formatResultRef.current(res) : res;
this.setState({
data: res,
error: undefined,
loading: false,
});
(_d = (_c = this.options).onSuccess) === null || _d === void 0 ? void 0 : _d.call(_c, res, params);
this.runPluginHandler('onSuccess', res, params);
(_f = (_e = this.options).onFinally) === null || _f === void 0 ? void 0 : _f.call(_e, params, res, undefined);
if (currentCount === this.count) {
this.runPluginHandler('onFinally', params, res, undefined);
}
return res;
}
catch (error) {
if (currentCount !== this.count) {
throw isCancelledError(error) ? error : new CancelledError();
}
this.setState({
error: error,
loading: false,
});
(_h = (_g = this.options).onError) === null || _h === void 0 ? void 0 : _h.call(_g, error, params);
this.runPluginHandler('onError', error, params);
(_k = (_j = this.options).onFinally) === null || _k === void 0 ? void 0 : _k.call(_j, params, undefined, error);
if (currentCount === this.count) {
this.runPluginHandler('onFinally', params, undefined, error);
}
throw error;
}
});
}
run(...params) {
this.runAsync(...params).catch((error) => {
// cancellation is not a failure: `run` never reports it
if (isCancelledError(error)) {
return;
}
if (!this.options.onError) {
console.error(error);
}
});
}
cancel() {
this.count += 1;
this.setState({
loading: false,
});
this.runPluginHandler('onCancel');
}
refresh() {
// @ts-ignore
this.run(...(this.state.params || []));
}
refreshAsync() {
// @ts-ignore
return this.runAsync(...(this.state.params || []));
}
mutate(data) {
const targetData = isFunction(data) ? data(this.state.data) : data;
this.runPluginHandler('onMutate', targetData);
this.setState({
data: targetData,
});
}
}