Skip to content

Instantly share code, notes, and snippets.

@tianyk
Last active August 12, 2022 07:12
Show Gist options
  • Save tianyk/5ba60182301c2ecb82802c107c728891 to your computer and use it in GitHub Desktop.
Save tianyk/5ba60182301c2ecb82802c107c728891 to your computer and use it in GitHub Desktop.
function throttle(func, threshold) {
let start = Date.now(), timer;
return function (...args) {
const ctx = this, curr = Date.now();
clearTimeout(timer);
if (curr - start >= threshold) {
func.apply(ctx, args);
start = curr;
} else {
const timeout = start + threshold - curr;
timer = setTimeout(() => {
func.apply(ctx, args);
start = curr;
}, timeout);
}
}
}
/**
*
* @param {string} key
* @returns
*/
async function get(key) {
return new Promise((reslove, reject) => {
_get(key, { reslove, reject });
});
}
const _get = (({ threshold } = { threshold: 200 }) => {
/**
* @type {{ key: string, promise: { reslove: (...args: any[]) => void; reject: (...args: any[]) => void; } }[]}
*/
let queue = [];
const invoke = throttle(async () => {
const _queue = queue;
queue = [];
try {
const values = await mget(_queue.map(task => task.key));
values.forEach((ret) => {
// _queue => map
const promise = _queue.find(task => task.key === ret.key).promise;
promise.reslove(ret.val);
})
} catch (err) {
// retry
queue.push(..._queue);
}
}, threshold);
/**
*/
return async (key, { reslove, reject }) => {
queue.push({ key, promise: { reslove, reject } });
invoke();
}
})();
/**
*
* @param {string[]} keys
* @returns {Promise<{key: string; val: string;}[]>}
*/
async function mget(keys) {
return new Promise((reslove) => {
setTimeout(() => {
reslove(keys.map(key => ({ key, val: `v#${key}` })));
}, 100);
});
}
Promise.all('.'.repeat(99).split('.').map((_, idx) => get(idx)))
.then((values) => values.forEach((val, idx) => console.log(val, idx)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment