Skip to content

Instantly share code, notes, and snippets.

@eabait
Created July 2, 2012 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eabait/3033778 to your computer and use it in GitHub Desktop.
Save eabait/3033778 to your computer and use it in GitHub Desktop.
REST Service Poller based on Web Workers and XMLHttpRequest object
var Ajax = {
httpRequest : null,
initXmlHttpObject : function() {
'use strict';
if (XMLHttpRequest) { // Chrome, Mozilla, Safari, ...
this.httpRequest = new XMLHttpRequest();
} else
if (ActiveXObject) { // IE
try {
this.httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
this.httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {}
}
}
},
sendRequest : function(config) {
'use strict';
if (!this.httpRequest) { //reuse the same object
this.initXmlHttpObject();
}
var req = this.httpRequest;
if (!req) {
return;
}
req.open('GET', config.url + '?' + this.stringifyParams(config.options), true);
//req.setRequestHeader('User-Agent','XMLHTTP/1.0');
req.onreadystatechange = function() {
if (req.readyState !== 4) {
return;
}
if (req.status !== 200 && req.status !== 304) {
config.error();
return;
}
config.success(req);
};
if (req.readyState === 4) {
return;
}
req.send();
},
stringifyParams : function(params) {
'use strict';
var keys = Object.keys(params),
i,
l,
s = [],
value;
for (i = 0, l = keys.length; i < l; ++i) {
value = (params[keys[i]] == null) ? '' : params[keys[i]];
s[s.length] = encodeURIComponent(keys[i]) + '=' + encodeURIComponent(value);
}
return s.join('&').replace(/%20/g, "+" );
}
};
var Poller = (function() {
'use strict';
return {
// number of failed requests
failed: 0,
// starting interval (1000 === 1 second)
interval: 10000,
timer: null,
url: null,
options: null,
// kicks off the setTimeout
init: function(){
if (this.timer) {
clearTimeout(this.timer);
}
this.timer = setTimeout(
this.getData.bind(this), // ensures 'this' is the poller obj inside getData, not the window object
this.interval
);
},
stop: function() {
clearTimeout(this.timer);
},
// get AJAX data + respond to it
getData: function(){
Ajax.sendRequest({
url: this.url,
options: this.options,
success: this.successHandler.bind(this),
error: this.errorHandler.bind(this)
});
},
successHandler : function(res) {
self.postMessage(res.response);
this.init();
},
// handle errors
errorHandler: function(){
if( ++this.failed < 10 ){
// give the server some breathing room by
// increasing the interval
this.interval += 1000;
// recurse
this.init();
}
}
};
}());
//Handle communication with web worker
self.addEventListener('message', function(e) {
'use strict';
var data = e.data;
switch (data.cmd) {
case 'start':
Poller.url = data.url;
Poller.options = data.options;
Poller.init(); //start polling
break;
case 'stop':
Poller.stop(); //clears the timeout
self.close(); // Terminates the worker.
break;
case 'updateConfig':
if (data.url) {
Poller.url = data.url;
}
if (data.options) {
Poller.options = data.options;
}
break;
default:
self.postMessage('Unknown command: ' + data);
}
}, false);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment