2

Please consider the following:

$(document).ready(function () {
    var promise;

    (function refresh(){
        promise = loadInfo();
        promise.done( function() {
            $.each(loadedData, function(key, value){
                $('#' + key + ' div.info').html(value.label);
            })
            // Call itself for next iteration
            window.setTimeout(refresh, 5 *1000);
        })
    })()
})
  • Do you think each iteration create a new var promise or they all reuse the same one?
  • In case a new var is created for each iteration, can I have an overload overtime (stack overflow!!!) ;) ? The application is displaying data and is supposed to run for long times
  • I also have another version with setInterval((function refresh(){...}), 5 *1000) without the setTimeout, which one is better? Thoughts?

Thank you

9
  • what you showed is not recursion in the classical sense, rather - chained calls with delay, therefore, stack overflow will not happen Commented Sep 1, 2015 at 16:14
  • @Igor since the refresh function calls itself, whether it's after a delay or not, it is still recursive. Commented Sep 1, 2015 at 16:18
  • 1
    @Jonathan.Brink - no, refresh function does not call itself Commented Sep 1, 2015 at 16:18
  • @Igor it's calling itself in this line: window.setTimeout(refresh, 5 *1000); Commented Sep 1, 2015 at 16:20
  • 2
    ^^ + setTimeout inside the loop is IMO preferable. Because, in case of long running indeterminate function call, setInterval may get overlap, whereas setTimeout will be called only when the call finishes and hence gives you a truer delay. Commented Sep 1, 2015 at 16:21

3 Answers 3

2

Since the promise variable is declared above the refresh function it is available via closure and will be re-used, so that shouldn't cause a stack overflow, but the implementation of loadInfo would determine if a new variable is created each time or not.

This might help shed some light on JavaScript and variable scoping: How do JavaScript closures work?

Perhaps a slightly cleaned up version could look like this:

$(document).ready(function () {
    (function refresh(){
        loadInfo().done( function(loadedData) {
            $.each(loadedData, function(key, value){
                $('#' + key + ' div.info').html(value.label);
            });
            // Call itself for next iteration
            window.setTimeout(refresh, 5 *1000);
        });
    })();
});

Using setInterval may be more readable to some eyes, but I think the setTimeout approach you have is fine.

Sign up to request clarification or add additional context in comments.

2 Comments

Nice! But a quick one: why pass loadedData as variable to the callback function? It's actually a global variable that is already available.
There may well be a valid reason for you to keep that as a global variable. I was just thinking that if it's possible to avoid the global variable to do so. Feel free to leave that out though if it's not conducive to your logic flow.
1

setInterval ensure periodic request(but doesn't ensure response order) but setTimeout(your code) doesn't ensure this. If there is long time response, the waiting time is also deferred. Plus if your loadInfo() request fails, need more code for next request.

The decision is up to your server environment and your app's priority.( between performance and accurateness )

Refer to my setTimeout code, if it'll help.

$(document).ready(function () {

    // for api
    function repeatLoad( cb ) {

        var bindedRepeatLoad = repeatLoad.bind( this, cb );
        var repeat = setTimeout.bind( this, bindedRepeatLoad, 5*1000 );

        loadInfo()
        .done( cb )
        .done( repeat )
        .error( repeat );
    }

    // for view
    function render( loadedData ) {
        $.each(loadedData, function(key, value){
            $('#' + key + ' div.info').html(value.label);
        });
    }

    // for app logic, only 1 line is needed.
    repeatLoad( render );
});

2 Comments

Great! I feel that I need to up my JS knowledge. Thank you! However I am accepting Jonathan.Brink's because it's more understandable for me.
@zwan thanks, Ye, that's just my style code. I like bind function because it makes code little less but sometime bind functions make it hard at first sight.
0

setTimeout in this current code will wait for the function to finish, then wait for the specified time and then calls the refresh function.

setInterval will keep calling the function after a given amount of time irrespective of whether the function has finished its execution or not

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.