PDA

View Full Version : Function extension: Function.waitUntil(waitConfig, obj, args, appendArgs)



vukbyte
29 Sep 2010, 4:42 PM
Here is some code that will delay execution of a function until some condition is met. This works similar to how createDelegate or defer work. It has been pretty helpful in preventing race conditions.



/*!
* WaitUntil function extension for Sencha ExtJS
* David Vukosa - http://www.marketo.com/
*
* Copyright 2010, Marketo
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* In other words, leave this credit and do whatever you want with the rest
*/

/*
* waitconfig - Configuration object for how the wait should behave
* - pollingFn : Function called on each polling interval. Controls when to stop polling and call the current function.
* Returns true to stop polling or false to continue.
* - pollInterval : Milliseconds to wait until the next polling function call. (100 ms default)
* - timeout : Total milliseconds to wait. (5 sec default)
* - timeoutFn : Function to call if the pollingFn conditions are not met and the timeout duration has been reached.
*
*/

// Executes the current funtion after some condition has been met
// Timeout support prevents the funtion from waiting forever.
Ext.applyIf(Function.prototype, {
waitUntil : function(waitConfig, obj, args, appendArgs) {
// Set polling configuration with defaults
var pollingConfig = {};
// Create the success funtion with is this functions delegate
pollingConfig['successFn'] = this.createDelegate(obj, args, appendArgs);

// Configure user specified polling properties
pollingConfig['pollInterval'] = waitConfig.pollInterval || 100;
pollingConfig['timeout'] = waitConfig.timeout || 5000;
pollingConfig['timeoutFn'] = waitConfig.timoutCallback || Ext.emptyFn;
pollingConfig['pollingFn'] = waitConfig.pollingTest || function(){return true;};

// Initialize status information
var statusInfo = {};
statusInfo['startTime'] = new Date();
statusInfo['pollCount'] = 1;

this._waitUntilPoller(pollingConfig, statusInfo);
},

_waitUntilPoller : function(pollingConfig, statusInfo) {
var elapsedTime = (new Date()).getTime() - statusInfo.startTime.getTime();

// Check if the polling test funtion has been satisfied
if (pollingConfig.pollingFn()) {
pollingConfig.successFn();
}
// Check for a timeout
else if (elapsedTime > pollingConfig.timeout) {
pollingConfig.timeoutFn();
}
// Otherwise continue polling
else {
statusInfo.pollCount++;
this._waitUntilPoller.defer(pollingConfig.pollInterval, this, [pollingConfig, statusInfo]);
}
}
});