UNPKG

wsemi

Version:

A support package for web developer.

187 lines (166 loc) 4.8 kB
import isfun from './isfun.mjs' import ispint from './ispint.mjs' import cint from './cint.mjs' /** * 函數去除抖動 * * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/debounce.test.mjs Github} * @memberOf wsemi * @param {Integer} [ms=300] 輸入未有調用的時間區間,為正整數,預設300ms * @example * * async function topAsync() { * * function test1() { * return new Promise((resolve, reject) => { * let ms = [] * * let dbc = debounce(300) * * let i = 0 * function core(name) { * i++ * ms.push({ name, i }) * console.log({ name, i }) * } * * setTimeout(function() { * dbc(() => { * core('A') * }) * }, 100) * setTimeout(function() { * dbc(() => { * core('B') * }) * }, 200) * setTimeout(function() { * dbc(() => { * core('C') * }) * }, 250) * setTimeout(function() { * dbc(() => { * core('D') * }) * }, 350) * setTimeout(function() { * dbc(() => { * core('E') * }) * }, 400) * setTimeout(function() { * resolve(ms) * }, 800) * }) * } * console.log('test1') * let r1 = await test1() * console.log(JSON.stringify(r1)) * // test1 * // { name: 'E', i: 1 } * // [{"name":"E","i":1}] * * function test2() { * return new Promise((resolve, reject) => { * let ms = [] * * let dbc = debounce(300) * * let i = 0 * function core(name) { * i++ * ms.push({ name, i }) * console.log({ name, i }) * } * * setTimeout(function() { * dbc(() => { * core('A') * }) * }, 50) * setTimeout(function() { * dbc(() => { * core('B') * }) * }, 100) * setTimeout(function() { * dbc(() => { * core('C') * }) * }, 150) * setTimeout(function() { * dbc(() => { * core('D') * }) * }, 500) * setTimeout(function() { * dbc(() => { * core('E') * }) * }, 550) * setTimeout(function() { * resolve(ms) * }, 1400) * }) * } * console.log('test2') * let r2 = await test2() * console.log(JSON.stringify(r2)) * // test2 * // { name: 'C', i: 1 } * // { name: 'E', i: 2 } * // [{"name":"C","i":1},{"name":"E","i":2}] * * } * topAsync().catch(() => {}) * */ function debounce(ms = 300) { function ClsDebounce(ms) { let q = [] //queue let t = null //timer let tLast = null //ms if (!ispint(ms)) { ms = 300 } ms = cint(ms) function detect() { if (t !== null) { return } t = setInterval(() => { //console.log('q', q) let tDiff = Date.now() - tLast if (tDiff > ms) { //超過指定延時則呼叫指定func //取最後的任務與清空佇列 let m = q.pop() q = [] //執行最後的任務 m.func(...m.input) } //clear if (q.length === 0) { clearInterval(t) t = null } }, 10) //10ms偵測, 啟動後跑timer, 無佇列則會停止減耗 } function run(func, ...input) { //check if (!isfun(func)) { console.log('func is not a function') return } //save tLast = Date.now() q.push({ func, input }) //detect detect() } return run } return new ClsDebounce(ms) } export default debounce