Skip to content

Instantly share code, notes, and snippets.

@westc
Last active September 7, 2023 16:05
Show Gist options
  • Save westc/8f902c593c4d85b9795514b36a187c12 to your computer and use it in GitHub Desktop.
Save westc/8f902c593c4d85b9795514b36a187c12 to your computer and use it in GitHub Desktop.
Continually polls for a change in a simple value (eg. primitive) returned by a function. Good for setting up a fake listener on something doesn't have another way to add a real event listener.
/**
* Continually calls `getValue()` with a state object that can be modified and
* the returned value will be compared to what was previously returned. If the
* return value is different than the previous, the `callback()` function will
* be called.
* @param {(currValue: any, state: State) => Value} getValue
* A function that is called after every interval (as specified by
* `msInterval`). The arguments passed will be (1) the previous value
* returned by this function and (2) the state object (which on the initial
* call starts off as an empty object but can be augmented). The return value
* is then compared to the previous return value to determine if `callback()`
* should be called.
* @param {(newValue: Value, oldValue: Value, state: State) => void} callback
* A function that is called only if the last return value of `getValue()` is
* different from the one before that.
* @param {?number=} msInterval
* Optional, defaults to 100. The amount of milliseconds to wait between
* polls.
* @returns {number}
* An ID that identifies the created timer. This value can be passed to
* `clearInterval()` to cancel the interval.
* @template State
* @template Value
*/
function pollChange(getValue, callback, msInterval) {
const state = {};
let lastValue = getValue(undefined, state);
return setInterval(() => {
const newValue = getValue(lastValue, state);
if (lastValue !== lastValue ? newValue === newValue : lastValue !== newValue) {
callback(newValue, lastValue, state);
}
lastValue = newValue;
}, msInterval ?? 100);
}
// Any time the hidden input field's value changes call triggerHiddenInputEvent().
pollChange(
() => document.getElementById('hiddenInput').value,
() => triggerHiddenInputEvent(document.getElementById('hiddenInput'))
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment