duoyun-ui
Version:
A lightweight desktop UI component library, implemented using Gem
107 lines • 2.99 kB
JavaScript
import { logger } from '@mantou/gem/helper/logger';
const setTimeout = globalThis.setTimeout;
/**Until the callback function resolve */
export async function forever(fn, interval = 1000) {
try {
return await fn();
}
catch (err) {
logger.error(err);
await sleep(interval);
return forever(fn, interval);
}
}
/**Polling calls until cancel */
export function polling(fn, delay) {
let timer = 0;
let hasExit = false;
const poll = async () => {
try {
await fn();
}
catch {
}
finally {
if (!hasExit) {
timer = setTimeout(poll, delay);
}
}
};
poll();
return (haveNext = false) => {
hasExit = true;
haveNext ? setTimeout(() => clearTimeout(timer), delay) : clearTimeout(timer);
};
}
export function sleep(ms = 3000) {
return new Promise((res) => setTimeout(res, ms));
}
export function nextFrame() {
return new Promise((resolve) => requestAnimationFrame(() => resolve(null)));
}
export function throttle(fn, wait = 500, { leading = false, maxWait = Infinity } = {}) {
let timer = 0;
let first = 0;
const exec = (...rest) => {
timer = setTimeout(() => (timer = 0), wait);
fn(...rest);
};
return (...rest) => {
const now = Date.now();
if (!timer)
first = now;
if (now - first > maxWait) {
first = now;
clearTimeout(timer);
exec(...rest);
}
else if (leading && !timer) {
exec(...rest);
}
else {
clearTimeout(timer);
timer = setTimeout(() => exec(...rest), wait);
}
};
}
export function debounce(fn, wait = 500, { leading = false } = {}) {
let timer = 0;
return (...args) => new Promise((resolve, reject) => {
clearTimeout(timer);
timer = setTimeout(() => {
timer = setTimeout(() => (timer = 0), wait);
Promise.resolve(fn(...args))
.then(resolve)
.catch(reject);
}, leading && !timer ? 0 : wait);
});
}
/**Invoke the function by condition */
export function invoke(fn, condition) {
let result;
let count = 0;
let invokeCount = 0;
let timestamp = 0;
let prevTimestamp = 0;
let invokeTimestamp = 0;
return (...rest) => {
prevTimestamp = timestamp;
timestamp = performance.now();
count++;
if (condition({ count, invokeCount, timestamp, prevTimestamp, invokeTimestamp })) {
invokeTimestamp = timestamp;
invokeCount++;
result = fn(...rest);
}
return result;
};
}
/**Only invoke first */
export function once(fn) {
return invoke(fn, ({ count }) => count === 1);
}
/**Ignore the first invoke */
export function omitOnce(fn) {
return invoke(fn, ({ count }) => count !== 1);
}
//# sourceMappingURL=timer.js.map