web-apps/vendor/touch/src/util/DelayedTask.js
2016-09-14 15:04:28 +03:00

152 lines
4.6 KiB
JavaScript

/**
* The DelayedTask class provides a convenient way to "buffer" the execution of a method,
* performing `setTimeout` where a new timeout cancels the old timeout. When called, the
* task will wait the specified time period before executing. If during that time period,
* the task is called again, the original call will be canceled. This continues so that
* the function is only called a single time for each iteration.
*
* This method is especially useful for things like detecting whether a user has finished
* typing in a text field. An example would be performing validation on a keypress. You can
* use this class to buffer the keypress events for a certain number of milliseconds, and
* perform only if they stop for that amount of time.
*
* Using {@link Ext.util.DelayedTask} is very simple:
*
* //create the delayed task instance with our callback
* var task = Ext.create('Ext.util.DelayedTask', {
* fn: function() {
* console.log('callback!');
* }
* });
*
* task.delay(1500); //the callback function will now be called after 1500ms
*
* task.cancel(); //the callback function will never be called now, unless we call delay() again
*
* ## Example
*
* @example
* //create a textfield where we can listen to text
* var field = Ext.create('Ext.field.Text', {
* xtype: 'textfield',
* label: 'Length: 0'
* });
*
* //add the textfield into a fieldset
* Ext.Viewport.add({
* xtype: 'formpanel',
* items: [{
* xtype: 'fieldset',
* items: [field],
* instructions: 'Type into the field and watch the count go up after 500ms.'
* }]
* });
*
* //create our delayed task with a function that returns the fields length as the fields label
* var task = Ext.create('Ext.util.DelayedTask', function() {
* field.setLabel('Length: ' + field.getValue().length);
* });
*
* // Wait 500ms before calling our function. If the user presses another key
* // during that 500ms, it will be canceled and we'll wait another 500ms.
* field.on('keyup', function() {
* task.delay(500);
* });
*
* @constructor
* The parameters to this constructor serve as defaults and are not required.
* @param {Function} fn The default function to call.
* @param {Object} scope The default scope (The `this` reference) in which the function is called. If
* not specified, `this` will refer to the browser window.
* @param {Array} args The default Array of arguments.
*/
Ext.define('Ext.util.DelayedTask', {
config: {
interval: null,
delay: null,
fn: null,
scope: null,
args: null
},
constructor: function(fn, scope, args) {
var config = {
fn: fn,
scope: scope,
args: args
};
this.initConfig(config);
},
/**
* Cancels any pending timeout and queues a new one.
* @param {Number} delay The milliseconds to delay
* @param {Function} newFn Overrides the original function passed when instantiated.
* @param {Object} newScope Overrides the original `scope` passed when instantiated. Remember that if no scope
* is specified, `this` will refer to the browser window.
* @param {Array} newArgs Overrides the original `args` passed when instantiated.
*/
delay: function(delay, newFn, newScope, newArgs) {
var me = this;
//cancel any existing queued functions
me.cancel();
//set all the new configurations
if (Ext.isNumber(delay)) {
me.setDelay(delay);
}
if (Ext.isFunction(newFn)) {
me.setFn(newFn);
}
if (newScope) {
me.setScope(newScope);
}
if (newScope) {
me.setArgs(newArgs);
}
//create the callback method for this delayed task
var call = function() {
me.getFn().apply(me.getScope(), me.getArgs() || []);
me.cancel();
};
me.setInterval(setInterval(call, me.getDelay()));
},
/**
* Cancel the last queued timeout
*/
cancel: function() {
this.setInterval(null);
},
/**
* @private
* Clears the old interval
*/
updateInterval: function(newInterval, oldInterval) {
if (oldInterval) {
clearInterval(oldInterval);
}
},
/**
* @private
* Changes the value into an array if it isn't one.
*/
applyArgs: function(config) {
if (!Ext.isArray(config)) {
config = [config];
}
return config;
}
});