A friend of mine needed a simple AJAX polling system, so I developed the AjaxPoller widget for him. The object is instantiated with a configuration object, which should include at the very least the URL to poll ('url'). Additionally, the developer can optionally specify: the length of time before the AJAX message times out ('timeout'), the length of time to wait between polls ('period'), a function to trigger when to stop polling dymanically ('stopfx'), and assign subscribers to any of the three CustomEvents ('onPoll', 'onStart', 'onStop').
Example: AjaxPoller
(function() {
// constants
var _YU = YAHOO.util,
_YL = YAHOO.lang,
_CE = _YU.CustomEvent,
_YC = YAHOO.util.Connect;
Core.Controller.AjaxPoller = function(conf) {
var _cfg = _YL.isObject(conf) ? conf : {};
if (! _YL.isNumber(_cfg.period)) {_cfg.period = 5000;} // default is 5 seconds
if (! _YL.isNumber(_cfg.timeout)) {_cfg.timeout = 10000;} // default is to abort AJAX after 10 seconds
if (! _YL.isFunction(_cfg.stopfx)) {_cfg.stopfx = function() {};}
if (! _YL.isString(_cfg.url)) {_cfg.url = '';}
this._cfg = _cfg;
this.onPoll = new _CE('AjaxPoller.poll', null, false, _CE.FLAT);
this.onStart = new _CE('AjaxPoller.start', null, false, _CE.FLAT);
this.onStop = new _CE('AjaxPoller.stop', null, false, _CE.FLAT);
if (_YL.isFunction(_cfg.onPoll)) {this.onPoll.subscribe(_cfg.onPoll);}
if (_YL.isFunction(_cfg.onStart)) {this.onStart.subscribe(_cfg.onStart);}
if (_YL.isFunction(_cfg.onStop)) {this.onStop.subscribe(_cfg.onStop);}
};
Core.Controller.AjaxPoller.prototype = {
onPoll: null,
onStart: null,
onStop: null,
_cfg: null,
_timeoutId: null,
_transaction: null,
start: function() {
var _that = this;
_that.onStart.fire(this);
var fx = function() {
_that._transaction = _YC.asyncRequest('GET', _that._cfg.url, {success: function(o) {
_that.onPoll.fire(o);
if (_that._cfg.stopfx(o)) {
_that.stop(o);
}
else {
_that._timeoutId = setTimeout(fx, _that._cfg.period);
}
}, failure: fx, timeout: _that._cfg.timeout});
};
fx();
},
stop: function() {
if (this._transaction && this._transaction) {this._transaction.conn.abort();}
if (this._timeoutId) {clearTimeout(this._timeoutId);}
this.onStop.fire.apply(this.onStop, arguments);
},
updateUrl: function(url) {
this._cfg.url = url;
}
};
})();
Once the poller has been instantiated, simply call the 'start' method to begin the system polling. Immediately upon calling the 'start' method, the 'onStart' CustomEvent fires, allowing developers to make any setup changes. Then the first AJAX request is made, and the 'onPoll' CustomEvent fires after each response, passing the response object to any subscribers. The same response object is then passed to the 'stopfx', which should return true if the polling should be terminated. Otherwise, the system continues to poll until the developer/user triggers a 'stop'. There the 'onStop' CustomEvent fires, passing the response object, if terminated by the 'stopfx' or null if terminated by the developer. If the 'url' changes over time, then the 'updateUrl' method should be called to modify the internal URL pointer.
Although the configuration object is exposed by the pseudo-private variable '_cfg', modifying it or any of the other pseudo-private variables directly should be avoided. I have put together a demo page so you can play with the system.