-
-
Save Integralist/d84d65c909eeafe4dfca to your computer and use it in GitHub Desktop.
define(['module/bootstrap'], function(news) { | |
var $ = news.$; | |
function seconds(secs) { | |
return secs * 1000; | |
} | |
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) { return status === 304 ? incrementDelay() : null; }, | |
function(status) { return status === 200 ? delay = seconds(5) : null; } | |
); | |
function success(data, status, xhr) { | |
checkStatus(xhr.status); | |
poll(endpoint); | |
} | |
function failure(xhr, status, error) { | |
incrementDelay(); | |
poll(endpoint); | |
} | |
function endpoint() { | |
$.ajax('http://localhost:3000/foobar', { timeout: limit }).then(success, failure); | |
} | |
function poll(endpoint) { | |
window.setTimeout(endpoint, delay); | |
} | |
var limit = seconds(5); // XHR timeout limit | |
var delay = seconds(5); // timer delay | |
var threshold = seconds(20); // timer delay threshold | |
poll(endpoint); | |
}); |
This is much harder than I initially thought it would be! The asynchronous nature of the whole thing (both the timeouts and the ajax requests) makes it tricky, and it's hard trying to work out a way of not resorting to storing state in variables across the function calls.
I really like the small seconds
and exists
functions, and being able to compose your checkStatus
method using dispatch
seems nice and functional to me. I started trying to think how I would solve this using OO (https://gist.github.com/danscotton/6be0c64188ec1ac42111) to see if that'd help me develop things in a functional way but that didn't really help at all! The main thing I was trying to achieve was to keep the polling behaviour (delays and thresholds) separate from the ajax behaviour (requests, status codes, timeouts).
You don't seem to yield the data from a successful request anywhere either? Is the purposefully not a requirement or would you eventually have to slot that in too?
Here's my attempt at trying to remove the delay
variable anyway, and passing it around in callbacks: https://gist.github.com/danscotton/828ee933b2afc0653db1. I just find that doing so litters most methods calls with the parameter, but this just might be my lack of understanding of writing functional code. Really need to read the functional js book! :)
I see what you're up to @Integralist :)