Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my function call that should be scheduled by setTimeout executed immediately? [duplicate]

Here's my issue. I have this function to test proxy servers.

function crawl() {
    var oldstatus = document.getElementById('status').innerHTML;
    document.getElementById('status').innerHTML = oldstatus + "Crawler Started...<br />";
    var url = document.getElementById('url').value;
    var proxys = document.getElementById('proxys').value.replace(/\n/g,',');

    var proxys = proxys.split(",");

    for (proxy in proxys) {
        var proxytimeout = proxy*10000;
        setTimeout(doRequest(url,proxys[proxy]), proxytimeout);
    }
}

I want the 'doRequest()' function to be called in roughly 10 second intervals but even with the setTimeout() the functions are called immediately.

Any ideas are welcome, thanks.

PS: Even if I put an arbitrary value for 'proxytimout' it has no effect.

like image 218
Ben Avatar asked Jan 10 '10 14:01

Ben


People also ask

Why does setTimeout run immediately?

This is because if you pass the parameters directly like this: setTimeout(greeting("Nathan", "Software developer"), 3000); Then JavaScript will immediately execute the function without waiting, because you're passing a function call and not a function reference as the first parameter.

Does setTimeout repeat?

setTimeout allows us to run a function once after the interval of time. setInterval allows us to run a function repeatedly, starting after the interval of time, then repeating continuously at that interval.

Can setTimeout cause memory leak?

setTimeout and setInterval are the two timing events available in JavaScript. The setTimeout function executes when the given time is elapsed, whereas setInterval executes repeatedly for the given time interval. These timers are the most common cause of memory leaks.

How many times setTimeout executed?

2 Answers. Save this answer. Show activity on this post. setTimeout will only execute once.


2 Answers

As you give the function to the setTimeout in that form, the function is executed instead of passed to the setTimeout. You have three alternatives to make it work:

Give first the function, then the timeout and the parameters as the last arguments:

setTimeout(doRequest, proxytimeout, url, proxys[proxy]);

Or just write a string that will be evaluated:

setTimeout('doRequest('+url+','+proxys[proxy]+')', proxytimeout);

Third style is to pass an anonymous function that calls the function. Note that in this case, you have to do it in a closure to prevent the values from changing in the loop, so it gets a bit tricky:

(function(u, p, t) {
    setTimeout(function() { doRequest(u, p); }, t);
})(url, proxys[proxy], proxytimeout);

The second format is a bit hacky, but works nevertheless if the arguments are scalar values (strings, ints etc). The third format is a bit unclear, so in this case the first option will obviously work best for you.

like image 175
Tatu Ulmanen Avatar answered Sep 21 '22 08:09

Tatu Ulmanen


This line here is the problem:

setTimeout(doRequest(url,proxys[proxy]), proxytimeout);

Writing doRequest() is actually calling the function. What you want is to pass the function itself:

setTimeout(doRequest, proxytime, url, proxys[proxy]);
like image 31
nickf Avatar answered Sep 20 '22 08:09

nickf