Skip to content

Instantly share code, notes, and snippets.

@lethak
Created December 5, 2018 20:05
Show Gist options
  • Save lethak/6494a08be4f76b040ff302499a8b9743 to your computer and use it in GitHub Desktop.
Save lethak/6494a08be4f76b040ff302499a8b9743 to your computer and use it in GitHub Desktop.
This class will apply a delay before resolving and returning your last callback.
const uuidv4 = require('uuid/v4')
const delayPromise = function (duration) {
return function (...args) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(...args)
}, duration)
})
}
}
/**
* This class will apply a delay before resolving and returning your last callback.
* Using this, you can push a spam of ajax query or whatever consuming task you want,
* and only the last one will be executed after a small delay while no more push are made,
*
* Usage:
* const callbackFn1 = function () { console.warn('callbackFn 1 EXEC !') return Promise.resolve(true) }
* const callbackFn2 = function () { console.warn('callbackFn 2 EXEC !') return Promise.resolve(true) }
* const CST = new CallbackSquashingThrottler()
* CST.push(callbackFn1).push(callbackFn2).then((r) => { console.log('THEN ! ', r) })
*/
export default class CallbackSquashingThrottler {
constructor (delayMs = 450) {
this._delayMs = delayMs
this._isEnabled = true
this._lastCallableRandId = null
}
get isEnabled () {
return this._isEnabled
}
set isEnabled (v) {
this._isEnabled = v
}
push (callable, force = false) {
if (!force && !this.isEnabled) {
console.error('Service is disabled (CallbackSquashingThrottler) ', this)
return Promise.reject()
}
if (typeof callable === 'function') {
const now = new Date()
const _lastCallableRandId = uuidv4()
this._lastCallableRandId = '' + _lastCallableRandId
let prom = new Promise((resolve, reject) => {
resolve({callable, date: now, randId: _lastCallableRandId})
})
return prom
.then(delayPromise(this._delayMs))
.then((delayed) => {
// console.warn('DELAYED ', delayed)
if (!force && !this.isEnabled) {
console.error('Service is disabled (CallbackSquashingThrottler) ', this)
} else if (force || (this.isEnabled && delayed.randId === this._lastCallableRandId)) {
this._lastCallableRandId = null
return delayed.callable()
}
return Promise.resolve(null)
})
} else {
console.error('callable must be a function')
}
return Promise.reject()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment