UNPKG

ht_hooks

Version:
185 lines (183 loc) 8.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _tslib = require("tslib"); var _utils = require("../../utils"); /* eslint-disable @typescript-eslint/no-parameter-properties */ 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 = (0, _tslib.__assign)((0, _tslib.__assign)((0, _tslib.__assign)({}, this.state), { loading: !options.manual }), initState); } Fetch.prototype.setState = function (s) { if (s === void 0) { s = {}; } this.state = (0, _tslib.__assign)((0, _tslib.__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, (0, _tslib.__spreadArray)([i], (0, _tslib.__read)(rest), false)); }).filter(Boolean); return Object.assign.apply(Object, (0, _tslib.__spreadArray)([{}], (0, _tslib.__read)(r), false)); }; Fetch.prototype.runAsync = function () { var params = []; for (var _i = 0; _i < arguments.length; _i++) { params[_i] = arguments[_i]; } return (0, _tslib.__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 (0, _tslib.__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 = (0, _tslib.__rest)(_a, ["stopNow", "returnNow"]); // stop request if (stopNow) { //!如果插件说 stopNow: true,就返回一个永不结束的 Promise,相当于彻底停止本次请求 return [2 /*return*/, new Promise(function () {})]; } this.setState((0, _tslib.__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, (0, _tslib.__spreadArray)([], (0, _tslib.__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, (0, _tslib.__spreadArray)([], (0, _tslib.__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, (0, _tslib.__spreadArray)([], (0, _tslib.__read)(this.state.params || []), false)); }; Fetch.prototype.refreshAsync = function () { // @ts-ignore return this.runAsync.apply(this, (0, _tslib.__spreadArray)([], (0, _tslib.__read)(this.state.params || []), false)); }; Fetch.prototype.mutate = function (data) { var targetData = (0, _utils.isFunction)(data) ? data(this.state.data) : data; this.runPluginHandler('onMutate', targetData); this.setState({ data: targetData }); }; return Fetch; }(); var _default = exports["default"] = Fetch;