I'm doing a very simple Comet-like long polling in JavaScript
The code below seems to work, but is it recursively calling itself and eating resources? How do I tell ?
EDIT: Code edited as per Dogberts suggestion
$(document).ready(function () {
function doSuccess(data) {
$('#res').html(data.time + "<br/>" + data.data);
startAjax();
}
function doError(jqXHR, textStatus, errorThrown) {
$('#res').html(textStatus + ":" + errorThrown);
startAjax();
}
function startAjax() {
$.ajax({
url: 'http://127.0.0.1:12345/',
dataType: 'jsonp',
success: doSuccess, //Edit: updated as per Dogbert's suggestion
error: doError
});
}
startAjax();
});
I've run http://home.orange.nl/jsrosman/ against it and it looks to be OK there (I'm just being professionally paranoid) startAjax calls (well callsBack) to doSuccess which calls startAjax
No, this shouldn't be eating any extra resources. You're properly calling the method after the old request has been completed.
On a side note, this
success: function (data) {
doSuccess(data);
},
error: function (jqXHR, textStatus, errorThrown) {
doError(jqXHR, textStatus, errorThrown);
}
could be written as
success: doSuccess,
error: doError
To me it looks ok: each new request is issued after the old one has expired
There is no recursion in that code, startAjax
exits pretty much immediately after it's called. you could do without redefining functions on every call though to minimize the memory use but the old functions are gc'd eventually anyway since there is no way to reference them. @Dogbert's answer shows how to avoid redefining the functions, but it's nothing critical as there are no permanent closures formed anyway.
Closure forming defined as: when an outer function is called that defines an inner function(s), and that(those) inner function(s) is(are) available after the outer function has exited.
Now, if you were to do the ajax in synchronous mode, then startAjax
would never exit and it would keep calling more startAjax
indirectly, and you would eventually reach the maximum call stack size. Not to mention your UI would be locked 100% of the time.
For example run this in google chrome and you will get:
RangeError: Maximum call stack size exceeded
function success(){
startAjax();
}
function error(){
startAjax();
}
function startAjax(){
synchronousAjax( success, error );
}
function synchronousAjax( success, error){
Math.random() < 0.5 ? success() : error();
}
startAjax();
Originally a comment on your question, but it got a bit longer than i expected...
This looks fine to me in terms of memory leaks - you're not assigning any variables anywhere so no problem for the garbage collector.
However, you may hit a stack overflow eventually, given the recursive nature of this approach - it never "bottoms out" to unwind the stack. Could you instead use setTimeout
to initiate the process periodically?