rc-hooks
Version:
React Hooks Library.
214 lines (213 loc) • 8.32 kB
JavaScript
"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;