forgeplus-react/node_modules/@ahooksjs/use-request/lib/useAsync.js

558 lines
16 KiB
JavaScript
Raw Normal View History

2023-07-29 21:19:10 +08:00
"use strict";
var __assign = this && this.__assign || function () {
__assign = Object.assign || function (t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) {
if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
}
return t;
};
return __assign.apply(this, arguments);
};
var __read = this && this.__read || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o),
r,
ar = [],
e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) {
ar.push(r.value);
}
} catch (error) {
e = {
error: error
};
} finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
} finally {
if (e) throw e.error;
}
}
return ar;
};
var __spread = this && this.__spread || function () {
for (var ar = [], i = 0; i < arguments.length; i++) {
ar = ar.concat(__read(arguments[i]));
}
return ar;
};
var __importDefault = this && this.__importDefault || function (mod) {
return mod && mod.__esModule ? mod : {
"default": mod
};
};
Object.defineProperty(exports, "__esModule", {
value: true
});
var lodash_debounce_1 = __importDefault(require("lodash.debounce"));
var lodash_throttle_1 = __importDefault(require("lodash.throttle"));
var react_1 = require("react");
var utils_1 = require("./utils");
var cache_1 = require("./utils/cache");
var limit_1 = __importDefault(require("./utils/limit"));
var usePersistFn_1 = __importDefault(require("./utils/usePersistFn"));
var useUpdateEffect_1 = __importDefault(require("./utils/useUpdateEffect"));
var windowFocus_1 = __importDefault(require("./utils/windowFocus"));
var windowVisible_1 = __importDefault(require("./utils/windowVisible"));
var DEFAULT_KEY = 'AHOOKS_USE_REQUEST_DEFAULT_KEY';
var Fetch =
/** @class */
function () {
function Fetch(service, config, subscribe, initState) {
// 请求时序
this.count = 0; // visible 后,是否继续轮询
this.pollingWhenVisibleFlag = false;
this.pollingTimer = undefined;
this.loadingDelayTimer = undefined;
this.unsubscribe = [];
this.that = this;
this.state = {
loading: false,
params: [],
data: undefined,
error: undefined,
run: this.run.bind(this.that),
mutate: this.mutate.bind(this.that),
refresh: this.refresh.bind(this.that),
cancel: this.cancel.bind(this.that),
unmount: this.unmount.bind(this.that)
};
this.service = service;
this.config = config;
this.subscribe = subscribe;
if (initState) {
this.state = __assign(__assign({}, this.state), initState);
}
this.debounceRun = this.config.debounceInterval ? lodash_debounce_1["default"](this._run, this.config.debounceInterval) : undefined;
this.throttleRun = this.config.throttleInterval ? lodash_throttle_1["default"](this._run, this.config.throttleInterval) : undefined;
this.limitRefresh = limit_1["default"](this.refresh.bind(this), this.config.focusTimespan);
if (this.config.pollingInterval) {
this.unsubscribe.push(windowVisible_1["default"](this.rePolling.bind(this)));
}
if (this.config.refreshOnWindowFocus) {
this.unsubscribe.push(windowFocus_1["default"](this.limitRefresh.bind(this)));
}
}
Fetch.prototype.setState = function (s) {
if (s === void 0) {
s = {};
}
this.state = __assign(__assign({}, this.state), s);
this.subscribe(this.state);
};
Fetch.prototype._run = function () {
var _this = this;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
} // 取消已有定时器
if (this.pollingTimer) {
clearTimeout(this.pollingTimer);
} // 取消 loadingDelayTimer
if (this.loadingDelayTimer) {
clearTimeout(this.loadingDelayTimer);
}
this.count += 1; // 闭包存储当次请求的 count
var currentCount = this.count;
this.setState({
loading: !this.config.loadingDelay,
params: args
});
if (this.config.loadingDelay) {
this.loadingDelayTimer = setTimeout(function () {
_this.setState({
loading: true
});
}, this.config.loadingDelay);
}
return this.service.apply(this, __spread(args)).then(function (res) {
if (currentCount !== _this.count) {
// prevent run.then when request is canceled
return new Promise(function () {});
}
if (_this.loadingDelayTimer) {
clearTimeout(_this.loadingDelayTimer);
}
var formattedResult = _this.config.formatResult ? _this.config.formatResult(res) : res;
_this.setState({
data: formattedResult,
error: undefined,
loading: false
});
if (_this.config.onSuccess) {
_this.config.onSuccess(formattedResult, args);
}
return formattedResult;
})["catch"](function (error) {
if (currentCount !== _this.count) {
// prevent run.then when request is canceled
return new Promise(function () {});
}
if (_this.loadingDelayTimer) {
clearTimeout(_this.loadingDelayTimer);
}
_this.setState({
data: undefined,
error: error,
loading: false
});
if (_this.config.onError) {
_this.config.onError(error, args);
} // If throwOnError, user should catch the error self,
// or the page will crash
if (_this.config.throwOnError) {
throw error;
}
console.error(error); // eslint-disable-next-line prefer-promise-reject-errors
return Promise.reject('useRequest has caught the exception, if you need to handle the exception yourself, you can set options.throwOnError to true.');
})["finally"](function () {
if (currentCount === _this.count) {
if (_this.config.pollingInterval) {
// 如果屏幕隐藏,并且 !pollingWhenHidden, 则停止轮询,并记录 flag等 visible 时,继续轮询
if (!utils_1.isDocumentVisible() && !_this.config.pollingWhenHidden) {
_this.pollingWhenVisibleFlag = true;
return;
}
_this.pollingTimer = setTimeout(function () {
_this._run.apply(_this, __spread(args));
}, _this.config.pollingInterval);
}
}
});
};
Fetch.prototype.run = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (this.debounceRun) {
this.debounceRun.apply(this, __spread(args)); // TODO 如果 options 存在 debounceInterval或 throttleInterval则 run 和 refresh 不会返回 Promise。 带类型需要修复后,此处变成 return;。
return Promise.resolve(null);
}
if (this.throttleRun) {
this.throttleRun.apply(this, __spread(args));
return Promise.resolve(null);
}
return this._run.apply(this, __spread(args));
};
Fetch.prototype.cancel = function () {
if (this.debounceRun) {
this.debounceRun.cancel();
}
if (this.throttleRun) {
this.throttleRun.cancel();
}
if (this.loadingDelayTimer) {
clearTimeout(this.loadingDelayTimer);
}
if (this.pollingTimer) {
clearTimeout(this.pollingTimer);
}
this.pollingWhenVisibleFlag = false;
this.count += 1;
this.setState({
loading: false
});
};
Fetch.prototype.refresh = function () {
return this.run.apply(this, __spread(this.state.params));
};
Fetch.prototype.rePolling = function () {
if (this.pollingWhenVisibleFlag) {
this.pollingWhenVisibleFlag = false;
this.refresh();
}
};
Fetch.prototype.mutate = function (data) {
if (typeof data === 'function') {
this.setState({
// eslint-disable-next-line react/no-access-state-in-setstate
data: data(this.state.data) || {}
});
} else {
this.setState({
data: data
});
}
};
Fetch.prototype.unmount = function () {
this.cancel();
this.unsubscribe.forEach(function (s) {
s();
});
};
return Fetch;
}();
function useAsync(service, options) {
var _options = options || {};
var _a = _options.refreshDeps,
refreshDeps = _a === void 0 ? [] : _a,
_b = _options.manual,
manual = _b === void 0 ? false : _b,
_c = _options.onSuccess,
onSuccess = _c === void 0 ? function () {} : _c,
_d = _options.onError,
onError = _d === void 0 ? function () {} : _d,
_e = _options.defaultLoading,
defaultLoading = _e === void 0 ? false : _e,
loadingDelay = _options.loadingDelay,
_f = _options.pollingInterval,
pollingInterval = _f === void 0 ? 0 : _f,
_g = _options.pollingWhenHidden,
pollingWhenHidden = _g === void 0 ? true : _g,
_h = _options.defaultParams,
defaultParams = _h === void 0 ? [] : _h,
_j = _options.refreshOnWindowFocus,
refreshOnWindowFocus = _j === void 0 ? false : _j,
_k = _options.focusTimespan,
focusTimespan = _k === void 0 ? 5000 : _k,
fetchKey = _options.fetchKey,
cacheKey = _options.cacheKey,
_l = _options.cacheTime,
cacheTime = _l === void 0 ? 5 * 60 * 1000 : _l,
_m = _options.staleTime,
staleTime = _m === void 0 ? 0 : _m,
debounceInterval = _options.debounceInterval,
throttleInterval = _options.throttleInterval,
initialData = _options.initialData,
_o = _options.ready,
ready = _o === void 0 ? true : _o,
_p = _options.throwOnError,
throwOnError = _p === void 0 ? false : _p;
var newstFetchKey = react_1.useRef(DEFAULT_KEY); // 持久化一些函数
var servicePersist = usePersistFn_1["default"](service);
var onSuccessPersist = usePersistFn_1["default"](onSuccess);
var onErrorPersist = usePersistFn_1["default"](onError);
var fetchKeyPersist = usePersistFn_1["default"](fetchKey);
var formatResult;
if ('formatResult' in _options) {
// eslint-disable-next-line prefer-destructuring
formatResult = _options.formatResult;
}
var formatResultPersist = usePersistFn_1["default"](formatResult);
var config = {
formatResult: formatResultPersist,
onSuccess: onSuccessPersist,
onError: onErrorPersist,
loadingDelay: loadingDelay,
pollingInterval: pollingInterval,
pollingWhenHidden: pollingWhenHidden,
// refreshOnWindowFocus should not work on manual mode
refreshOnWindowFocus: !manual && refreshOnWindowFocus,
focusTimespan: focusTimespan,
debounceInterval: debounceInterval,
throttleInterval: throttleInterval,
throwOnError: throwOnError
};
var subscribe = usePersistFn_1["default"](function (key, data) {
setFetches(function (s) {
// eslint-disable-next-line no-param-reassign
s[key] = data;
return __assign({}, s);
});
});
var _q = __read(react_1.useState(function () {
var _a; // 如果有 缓存,则从缓存中读数据
if (cacheKey) {
var cacheData_1 = (_a = cache_1.getCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
if (cacheData_1) {
newstFetchKey.current = cacheData_1.newstFetchKey;
/* 使用 initState, 重新 new Fetch */
var newFetches_1 = {};
Object.keys(cacheData_1.fetches).forEach(function (key) {
var cacheFetch = cacheData_1.fetches[key];
var newFetch = new Fetch(servicePersist, config, subscribe.bind(null, key), {
loading: cacheFetch.loading,
params: cacheFetch.params,
data: cacheFetch.data,
error: cacheFetch.error
});
newFetches_1[key] = newFetch.state;
});
return newFetches_1;
}
}
return {};
}), 2),
fetches = _q[0],
setFetches = _q[1];
var fetchesRef = react_1.useRef(fetches);
fetchesRef.current = fetches;
var readyMemoryParams = react_1.useRef();
var run = react_1.useCallback(function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (!ready) {
// 没有 ready, 记录请求参数,等 ready 后,发起请求用
readyMemoryParams.current = args;
return;
}
if (fetchKeyPersist) {
var key = fetchKeyPersist.apply(void 0, __spread(args));
newstFetchKey.current = key === undefined ? DEFAULT_KEY : key;
}
var currentFetchKey = newstFetchKey.current; // 这里必须用 fetchsRef而不能用 fetches。
// 否则在 reset 完,立即 run 的时候,这里拿到的 fetches 是旧的。
var currentFetch = fetchesRef.current[currentFetchKey];
if (!currentFetch) {
var newFetch = new Fetch(servicePersist, config, subscribe.bind(null, currentFetchKey), {
data: initialData
});
currentFetch = newFetch.state;
setFetches(function (s) {
// eslint-disable-next-line no-param-reassign
s[currentFetchKey] = currentFetch;
return __assign({}, s);
});
}
return currentFetch.run.apply(currentFetch, __spread(args));
}, [fetchKey, subscribe, ready]);
var runRef = react_1.useRef(run);
runRef.current = run; // cache
useUpdateEffect_1["default"](function () {
if (cacheKey) {
cache_1.setCache(cacheKey, cacheTime, {
fetches: fetches,
newstFetchKey: newstFetchKey.current
});
}
}, [cacheKey, fetches]); // for ready
var hasTriggeredByReady = react_1.useRef(false);
useUpdateEffect_1["default"](function () {
if (ready) {
if (!hasTriggeredByReady.current && readyMemoryParams.current) {
runRef.current.apply(runRef, __spread(readyMemoryParams.current));
}
hasTriggeredByReady.current = true;
}
}, [ready]); // 第一次默认执行
react_1.useEffect(function () {
var _a;
if (!manual) {
// 如果有缓存,则重新请求
if (Object.keys(fetches).length > 0) {
// 如果 staleTime 是 -1则 cache 永不过期
// 如果 statleTime 超期了,则重新请求
var cacheStartTime = cacheKey && ((_a = cache_1.getCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.startTime) || 0;
if (!(staleTime === -1 || new Date().getTime() - cacheStartTime <= staleTime)) {
/* 重新执行所有的 cache */
Object.values(fetches).forEach(function (f) {
f.refresh();
});
}
} else {
// 第一次默认执行,可以通过 defaultParams 设置参数
runRef.current.apply(runRef, __spread(defaultParams));
}
}
}, []); // 重置 fetches
var reset = react_1.useCallback(function () {
Object.values(fetchesRef.current).forEach(function (f) {
f.unmount();
});
newstFetchKey.current = DEFAULT_KEY;
setFetches({}); // 不写会有问题。如果不写,此时立即 run会是老的数据
fetchesRef.current = {};
}, [setFetches]); // refreshDeps 变化,重新执行所有请求
useUpdateEffect_1["default"](function () {
if (!manual) {
/* 全部重新执行 */
Object.values(fetchesRef.current).forEach(function (f) {
f.refresh();
});
}
}, __spread(refreshDeps)); // 卸载组件触发
react_1.useEffect(function () {
return function () {
Object.values(fetchesRef.current).forEach(function (f) {
f.unmount();
});
};
}, []);
var notExecutedWarning = react_1.useCallback(function (name) {
return function () {
console.warn("You should't call " + name + " when service not executed once.");
};
}, []);
return __assign(__assign({
loading: ready && !manual || defaultLoading,
data: initialData,
error: undefined,
params: [],
cancel: notExecutedWarning('cancel'),
refresh: notExecutedWarning('refresh'),
mutate: notExecutedWarning('mutate')
}, fetches[newstFetchKey.current] || {}), {
run: run,
fetches: fetches,
reset: reset
});
}
exports["default"] = useAsync;