Skip to content

Instantly share code, notes, and snippets.

@danscotton
Forked from Integralist/fp polling xhr.js
Created June 24, 2014 15:23
Show Gist options
  • Save danscotton/828ee933b2afc0653db1 to your computer and use it in GitHub Desktop.
Save danscotton/828ee933b2afc0653db1 to your computer and use it in GitHub Desktop.
define(['module/bootstrap'], function(news) {
var $ = news.$;
function seconds(secs) {
return secs * 1000;
}
function double(num) {
return num * 2;
}
function min(a, b) {
return Math.min(a, b);
}
// function incrementDelay() {
// // don't want the delay to become ridiculous so I set a threshold I don't want it to go beyond
// if (delay < threshold) {
// delay *= 2;
// }
// return delay; // we return a value for the sake of our `dispatch` method called by `checkStatus`
// }
function exists(value) {
return value !== undefined && value !== null;
}
function dispatch() {
var fns = Array.prototype.slice.call(arguments, 0);
var size = fns.length;
return function(target) {
var ret;
for (var i = 0; i < size; i++) {
var fn = fns[i];
ret = fn.call(fn, target);
if (exists(ret)) {
return ret; // break out of the loop as we've executed a function that doesn't return null
}
}
return ret;
};
}
var checkStatus = dispatch(
function(status, delay, callback) { return status === 304 ? callback(min(double(delay), threshold) : null; },
function(status, delay, callback) { return status === 200 ? callback(seconds(5)) : null; },
function(status, delay, callback) { callback(min(double(delay), threshold); /* always increase delay as we've fallen through the fn stack */ }
);
// function success(data, status, xhr) {
// checkStatus(xhr.status);
// poll(endpoint);
// }
// function failure(xhr, status, error) {
// incrementDelay();
// poll(endpoint);
// }
function endpoint(url, delay) {
$.ajax(url, { timeout: limit }).then(
function(data, status, xhr) {
checkStatus(xhr.status, delay, function(newDelay) {
poll(url, newDelay);
});
},
function(xhr, status, error) {
checkStatus(xhr.status, delay, function(newDelay) {
poll(url, newDelay);
});
}
);
}
function poll(url, delay) {
window.setTimeout(endpoint(url, delay), delay);
}
var limit = seconds(5); // XHR timeout limit
// var delay = seconds(5); // timer delay
var threshold = seconds(20); // timer delay threshold
poll('http://localhost:3000/foobar', seconds(5));
});
@danscotton
Copy link
Author

My attempt at trying to remove the 'global' delay variable, but I find that passing it around in so many functions makes the code even more confusing!

@Integralist
Copy link

Yeah this was the problem I was encountering. The code here: https://gist.github.com/Integralist/d84d65c909eeafe4dfca (IMHO) is much clearer but I'm losing compossibility and introducing a single point (delay) for mutation. But I wonder whether it's worth it or not?

@danscotton
Copy link
Author

I would say it is worth having that delay variable, as the code is much clearer and easier to understand compared to passing it around. Every variable you could possibly introduce would seemingly suffer the same problem with my approach too, resulting in even more confusing method signatures and a lot more repetition. You actually mutate the delay variable from two points in the code, but to refactor that to just one method (setDelay) or something would end up breaking your dispatch function because it relies upon a value to be returned. Maybe a bit more refactoring could clean that up though? Again, at this level it seems quite finicky and not entirely sure where the gains are?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment