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.