import { makeLog } from "../../utils/devOnly";
import { cancelIdleCb, reqIdleCb } from "./IdleDeadline";
const log = makeLog('DeferValue');
/**
* initializ value when idle.
* @author: Aamir khan
* @example
* const formatter = new DeferValue(() => {
return new Intl.DateTimeFormat('en-US', {
timeZone: 'America/Los_Angeles',
});
});
console.log(this.formatter.getValue().format(new Date()));
Note: If you’re in a situation where you want to use the DeferValue class but you can’t change your public API,
you can use the DeferValue with getters or use `defineDeferProp`
*/
class DeferValue {
/**
* Accepts a function to initialize the value of a variable when idle.
* @param {Function} init
*/
constructor(init) {
this.init_ = init;
log('making a new defer value');
/** @private */
this.value_ = undefined;
/** @private */
this.idleHandle_ = reqIdleCb(() => {
this.value_ = this.init_();
log('idleHandle called', this.value_);
});
}
/**
* Returns the value if it's already been initialized. If it hasn't then the
* initializer function is run immediately and the pending idle callback
* is cancelled.
* @return {?} depends on the init function
*/
getValue() {
if (this.value_ === undefined) {
log('DeferValue is undefined');
this.cancleIdleInit_();
this.value_ = this.init_();
}
log('getValue called', this.value_);
return this.value_;
}
/**
* Cancels any scheduled requestIdleCallback
* and sets the new value as defer value
* @param {?} newValue value for the DeferValue
*/
setValue(newValue) {
this.cancleIdleInit_();
this.value_ = newValue;
}
/**
* Cancels any scheduled requestIdleCallback and resets the handle.
* @private
*/
cancleIdleInit_() {
if (this.idleHandle_) {
cancelIdleCb(this.idleHandle_);
this.idleHandle_ = null;
log('cancleIdleInit called');
}
}
}
export default DeferValue;