UNPKG

rc-hooks

Version:
214 lines (213 loc) 8.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCache = getCache; exports.clearCache = clearCache; var tslib_1 = require("tslib"); var ut2_1 = require("ut2"); var util_helpers_1 = require("util-helpers"); var dom_1 = require("../utils/dom"); var windowVisible_1 = tslib_1.__importDefault(require("../utils/windowVisible")); var windowFocus_1 = tslib_1.__importDefault(require("../utils/windowFocus")); var config_1 = require("../utils/config"); var asyncMemo = new util_helpers_1.AsyncMemo({ prefix: config_1.pkgName, stdTTL: 5 * 60 * 1000 }); /** * 获取缓存键值。 * * @param key 键名称。 * @returns 如果找到缓存键值,返回该键值,否则返回 `undefined`。 */ function getCache(key) { return asyncMemo.cache.get(key); } /** * 清理 `useAsync` 缓存。如果不传参数,表示清理全部。 * * @param key 键名称。 */ function clearCache(key) { if (key) { asyncMemo.cache.del(key); } else { asyncMemo.cache.clear(); } } var Async = /** @class */ (function () { function Async(async, options) { // 内部缓存参数 this.params = []; // 标识页面获取焦点时是否触发轮询 this.pollingWhenVisibleFlag = false; // 轮询定时器 this.pollingTimer = null; // 内部标记当前执行计数,防止同一个实例执行多次run 或 不执行取消后的run this.counter = 1; // 标识是否销毁 this.destroyed = false; this.async = async; this.options = tslib_1.__assign({ cacheTime: 5 * 60 * 1000, persisted: false, pollingWhenHidden: true, refreshOnWindowFocus: false, focusTimespan: 5000 }, options); // 取消订阅列表 this.unsubscribes = []; this.init(); } // 初始化 Async.prototype.init = function () { var _a = this.options, pollingInterval = _a.pollingInterval, refreshOnWindowFocus = _a.refreshOnWindowFocus, focusTimespan = _a.focusTimespan; // 延迟执行 this.updateDebounce(); // 订阅页面显示时触发轮询 if (pollingInterval) { this.unsubscribes.push((0, windowVisible_1.default)(this.rePolling.bind(this))); } // 订阅屏幕聚焦时请求 if (refreshOnWindowFocus) { var limitRefresh = (0, ut2_1.limit)(this.refresh.bind(this), focusTimespan); this.unsubscribes.push((0, windowFocus_1.default)(limitRefresh)); } }; // 更新延迟执行 Async.prototype.updateDebounce = function () { var _a = this.options, debounceInterval = _a.debounceInterval, throttleInterval = _a.throttleInterval; this.debounce = typeof debounceInterval === 'number' && debounceInterval > 0 ? (0, ut2_1.debounce)(this._run, debounceInterval) : undefined; this.throttle = typeof throttleInterval === 'number' && throttleInterval > 0 ? (0, ut2_1.throttle)(this._run, throttleInterval) : undefined; }; // 轮询 Async.prototype.rePolling = function () { if (this.pollingWhenVisibleFlag) { this.pollingWhenVisibleFlag = false; this.refresh(); } }; Async.prototype.afterUpdateOptions = function (prevOptions, nextOptions) { if (nextOptions === void 0) { nextOptions = {}; } // 可能取消延迟 if (('debounceInterval' in nextOptions && nextOptions.debounceInterval !== prevOptions.debounceInterval) || ('throttleInterval' in nextOptions && nextOptions.throttleInterval !== prevOptions.throttleInterval)) { this.updateDebounce(); } }; // 更新配置 Async.prototype.updateOptions = function (options) { var prevOptions = this.options; var nextOptions = tslib_1.__assign(tslib_1.__assign({}, this.options), options); this.options = nextOptions; this.afterUpdateOptions(prevOptions, nextOptions); }; // 发起请求 // 不返回Promise,只支持 onSuccess 或 onError 回调处理,避免多个实例同时调用 run 导致部分 Promise 没有触发问题 Async.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); } // 防止执行取消的异步结果 // 触发多次run,只有执行最后一次异步结果 var count = this.counter; this.params = args; var _a = this.options, cacheKey = _a.cacheKey, cacheTime = _a.cacheTime, persisted = _a.persisted, formatResult = _a.formatResult, onSuccess = _a.onSuccess, onError = _a.onError, onFinally = _a.onFinally, onBefore = _a.onBefore, pollingWhenHidden = _a.pollingWhenHidden, pollingInterval = _a.pollingInterval; onBefore === null || onBefore === void 0 ? void 0 : onBefore(args); return new Promise(function (resolve, reject) { asyncMemo .run(function () { return _this.async.apply(_this, args).then(function (res) { return typeof formatResult === 'function' ? formatResult(res, args) : res; }); }, cacheKey, { persisted: persisted, ttl: cacheTime }) .then(function (fmtRes) { if (count === _this.counter) { onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(fmtRes, args); resolve(fmtRes); } }) .catch(function (err) { if (count === _this.counter) { onError === null || onError === void 0 ? void 0 : onError(err, args); reject(err); } }) .finally(function () { if (count === _this.counter) { onFinally === null || onFinally === void 0 ? void 0 : onFinally(); if (pollingInterval) { if (!(0, dom_1.isDocumentVisible)() && !pollingWhenHidden) { _this.pollingWhenVisibleFlag = true; return; } _this.pollingTimer = setTimeout(function () { _this.run.apply(_this, args); }, pollingInterval); } } }); }); }; // 执行异步 Async.prototype.run = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (this.debounce) { this.debounce.apply(this, args); return Promise.resolve(null); } if (this.throttle) { this.throttle.apply(this, args); return Promise.resolve(null); } this.counter += 1; return this._run.apply(this, args); }; // 使用之前参数,重新执行异步 Async.prototype.refresh = function () { return this.run.apply(this, this.params); }; // 取消请求 Async.prototype.cancel = function () { if (this.debounce) { this.debounce.cancel(); } if (this.throttle) { this.throttle.cancel(); } // 取消轮询定时器 if (this.pollingTimer) { clearTimeout(this.pollingTimer); this.pollingTimer = null; } this.counter += 1; }; // 销毁 Async.prototype.destroy = function (needCancel) { if (needCancel === void 0) { needCancel = true; } if (needCancel) { this.cancel(); } if (!this.destroyed) { this.destroyed = true; this.unsubscribes.forEach(function (s) { return s(); }); this.unsubscribes = []; } }; // 恢复 Async.prototype.resume = function () { if (this.destroyed) { this.destroyed = false; this.init(); } }; return Async; }()); exports.default = Async;