ht_hooks
Version:
ht React 业务 Hooks
178 lines • 8.05 kB
JavaScript
import { __assign, __awaiter, __generator, __read, __rest, __spreadArray } from "tslib";
/* eslint-disable @typescript-eslint/no-parameter-properties */
import { isFunction } from '../../utils';
var Fetch = /** @class */function () {
function Fetch(serviceRef,
//请求本体
options, subscribe,
//更新的方法
initState) {
if (initState === void 0) {
initState = {};
}
this.serviceRef = serviceRef;
this.options = options;
this.subscribe = subscribe;
this.initState = initState;
this.count = 0;
this.state = {
loading: false,
// 请求是否进行中
params: undefined,
// 上一次请求用的参数
data: undefined,
// 请求成功后的数据
error: undefined // 请求失败后的错误
};
this.state = __assign(__assign(__assign({}, this.state), {
loading: !options.manual
}), initState);
}
Fetch.prototype.setState = function (s) {
if (s === void 0) {
s = {};
}
this.state = __assign(__assign({}, this.state), s);
this.subscribe();
};
Fetch.prototype.runPluginHandler = function (event) {
var rest = [];
for (var _i = 1; _i < arguments.length; _i++) {
rest[_i - 1] = arguments[_i];
}
// @ts-ignore
var r = this.pluginImpls.map(function (i) {
var _a;
return (_a = i[event]) === null || _a === void 0 ? void 0 : _a.call.apply(_a, __spreadArray([i], __read(rest), false));
}).filter(Boolean);
return Object.assign.apply(Object, __spreadArray([{}], __read(r), false));
};
Fetch.prototype.runAsync = function () {
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
return __awaiter(this, void 0, void 0, function () {
var currentCount, _a, _b, stopNow, _c, returnNow, state //修改状态,比如提前设置 data 或 loading = false
, servicePromise, res, error_1;
var _d;
var _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
return __generator(this, function (_q) {
switch (_q.label) {
case 0:
this.count += 1; //#全局最新请求的编号,每次+1
currentCount = this.count;
_a = this.runPluginHandler('onBefore', params), _b = _a.stopNow, stopNow = _b === void 0 ? false : _b, _c = _a.returnNow, returnNow = _c === void 0 ? false : _c, state = __rest(_a, ["stopNow", "returnNow"]);
// stop request
if (stopNow) {
//!如果插件说 stopNow: true,就返回一个永不结束的 Promise,相当于彻底停止本次请求
return [2 /*return*/, new Promise(function () {})];
}
this.setState(__assign({
loading: true,
//开始 loading
params: params
}, state));
// return now
if (returnNow) {
return [2 /*return*/, Promise.resolve(state.data)]; //!如果插件说 returnNow: true,就直接返回缓存数据,不发请求
}
(_f = (_e = this.options).onBefore) === null || _f === void 0 ? void 0 : _f.call(_e, params); //#执行外部配置的 onBefore 回调(如果有)(这个是配置里的onBefore钩子不是插件的onBefore钩子)
_q.label = 1;
case 1:
_q.trys.push([1, 3,, 4]);
servicePromise = this.runPluginHandler('onRequest', this.serviceRef.current, params).servicePromise;
if (!servicePromise) {
servicePromise = (_d = this.serviceRef).current.apply(_d, __spreadArray([], __read(params), false)); //!如果插件没有返回 Promise,才调用用户传入的真正请求( service函数 )
}
return [4 /*yield*/, servicePromise];
case 2:
res = _q.sent();
if (currentCount !== this.count) {
//#判断请求是否还有效,如果在请求过程中用户取消或发起了新的请求(this.count 已变),丢弃本次结果。
// prevent run.then when request is canceled
return [2 /*return*/, new Promise(function () {})];
}
// const formattedResult = this.options.formatResultRef.current ? this.options.formatResultRef.current(res) : res;
this.setState({
data: res,
//保存数据
error: undefined,
//清空错误,因为已请求成功
loading: false //结束 loading因为已请求完毕
});
(_h = (_g = this.options).onSuccess) === null || _h === void 0 ? void 0 : _h.call(_g, res, params); // #执行option配置的 onSuccess 回调
this.runPluginHandler('onSuccess', res, params); //#执行插件的 onSuccess 钩子
(_k = (_j = this.options).onFinally) === null || _k === void 0 ? void 0 : _k.call(_j, params, res, undefined);
if (currentCount === this.count) {
this.runPluginHandler('onFinally', params, res, undefined); //#执行 onFinally 回调和插件钩子(只有当前请求还有效才执行插件的 onFinally)
}
return [2 /*return*/, res];
//#最终返回请求结果
case 3:
error_1 = _q.sent();
if (currentCount !== this.count) {
//同样检查请求是否还有效,如果是旧请求就丢弃
// prevent run.then when request is canceled
return [2 /*return*/, new Promise(function () {})];
}
this.setState({
error: error_1,
//请求错误
loading: false //结束loading因为已请求完毕
});
(_m = (_l = this.options).onError) === null || _m === void 0 ? void 0 : _m.call(_l, error_1, params); // 执行外部的 onError 回调和插件的 onError 钩子
this.runPluginHandler('onError', error_1, params);
(_p = (_o = this.options).onFinally) === null || _p === void 0 ? void 0 : _p.call(_o, params, undefined, error_1);
if (currentCount === this.count) {
this.runPluginHandler('onFinally', params, undefined, error_1); // 请求失败的情况下,同样执行 onFinally 钩子,传入错误信息
}
throw error_1;
//抛出错误,让调用 runAsync() 的地方可以 catch 到
case 4:
return [2 /*return*/];
}
});
});
};
Fetch.prototype.run = function () {
var _this = this;
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
this.runAsync.apply(
//#用来手动发起请求(非 async),不返回 Promise,适合直接触发使用。
this, __spreadArray([], __read(params), false)).catch(function (error) {
if (!_this.options.onError) {
console.error(error);
}
});
};
Fetch.prototype.cancel = function () {
this.count += 1; //让正在进行的请求失效(因为 runAsync 每次开始也会检查 count,如果不是最新就丢弃)
this.setState({
loading: false
});
this.runPluginHandler('onCancel'); //调用插件的 onCancel 钩子(比如用在防抖、节流、轮询里,取消定时器等)
};
Fetch.prototype.refresh = function () {
// @ts-ignore 假设你第一次是 run(1, 2),那 refresh() 等价于 run(1, 2),不需要你再传参。
this.run.apply(
//#用上次请求参数重新请求
this, __spreadArray([], __read(this.state.params || []), false));
};
Fetch.prototype.refreshAsync = function () {
// @ts-ignore
return this.runAsync.apply(this, __spreadArray([], __read(this.state.params || []), false));
};
Fetch.prototype.mutate = function (data) {
var targetData = isFunction(data) ? data(this.state.data) : data;
this.runPluginHandler('onMutate', targetData);
this.setState({
data: targetData
});
};
return Fetch;
}();
export default Fetch;