Is the code below using memory recursively

2019-09-09 07:03发布

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

4条回答
一纸荒年 Trace。
2楼-- · 2019-09-09 07:48

To me it looks ok: each new request is issued after the old one has expired

查看更多
劳资没心,怎么记你
3楼-- · 2019-09-09 07:54

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
查看更多
该账号已被封号
4楼-- · 2019-09-09 08:02

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();
查看更多
Anthone
5楼-- · 2019-09-09 08:07

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?

查看更多
登录 后发表回答