4

I have the following script:

$(function() {
    $(".message").hide();

    function simulate_ajax_call()
    {
        $.ajax({
            url: "/echo/json/",
            success: function(){
                alert("done");
                $(".message").empty().html("done");
                $(".message").delay(1000).fadeOut(500);
            }
        });
    }

    $('.button').click(function() {
        $(".message").fadeIn(500);
        setTimeout("simulate_ajax_call()", 5000);
    });
});

With the following HTML:

<input type="button" value="button" class="button" />
<div class="message">loading...</div>

For some reason the setTimeout part is not working. i.e. it does not seem to call the function after 5000ms.

jsFiddle.

alex
  • 479,566
  • 201
  • 878
  • 984
oshirowanen
  • 15,297
  • 82
  • 198
  • 350
  • Basic debugging first. You are 100% sure this is because of the timeout and not because of a problem in the Ajax call? – Pekka Feb 13 '11 at 08:41
  • Anyway, whatever you do, you should be using `setTimeout(function() { simulate_ajax_call();}, 5000);` – Pekka Feb 13 '11 at 08:41
  • @Pekka Or `setTimeout(simulate_ajax_call, 5000);` - No need to wrap a function invocation within another function. Functions are [first-class](http://en.wikipedia.org/wiki/First-class_function), remember? :P – Jacob Relkin Feb 13 '11 at 08:43
  • 1
    @Jacob fair enough! I tend to prefer the function notation though, in case I need to add something (like a parameter) later. – Pekka Feb 13 '11 at 08:44

3 Answers3

10

You need to replace:

setTimeout("simulate_ajax_call()", 5000);

with:

setTimeout(simulate_ajax_call, 5000);

Check out the working example


You should avoid putting () at the end of the function name because otherwise it gets called/run immediately :)

Community
  • 1
  • 1
Sarfraz
  • 377,238
  • 77
  • 533
  • 578
4

You need to drop the quotes and the parenthesis.

Doing setTimeout("simulate_ajax_call()", 5000) is equivalent of eval()ing that code, which is automatically running the function.

alex
  • 479,566
  • 201
  • 878
  • 984
1

setTimeout evals its string argument in the global scope, but simulate_ajax_call is declared in a nested scope, so the eval can't find it in order to invoke it.

As the other two answers point out the best way to resolve the issue is to use the function-passing version of setTimeout, but being careful to remove the parentheses, because you don't want to accidentally invoke the function immediately.

Your code would probably have worked had you declared simulate_ajax_call at the global scope. The parentheses would have been correct in this case, although the string version of setTimeout is still a bad idea in general.

Neil
  • 54,642
  • 8
  • 60
  • 72