Почему мой вызов функции должен быть запланирован с помощью setTimeout, выполняемого немедленно?

Вот моя проблема. У меня есть эта функция для проверки прокси-серверов.

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);
    }
}

Я хочу, чтобы функция doRequest() была вызвана примерно через 10 секунд, но даже с помощью setTimeout() функции вызываются немедленно.

Любые идеи приветствуются, спасибо.

PS: Даже если я помещаю произвольное значение для 'proxytimout', это не имеет никакого эффекта.

Ответ 1

Как вы передаете функцию setTimeout в этой форме, функция выполняется вместо переданного в setTimeout. У вас есть три альтернативы, чтобы заставить его работать:

Дайте сначала функцию, затем тайм-аут и параметры в качестве последних аргументов:

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

Или просто напишите строку, которая будет оценена:

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

Третий стиль - передать анонимную функцию, вызывающую функцию. Обратите внимание, что в этом случае вы должны сделать это в закрытии, чтобы предотвратить изменение значений в цикле, поэтому он становится немного сложным:

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

Второй формат немного взломан, но все же работает, если аргументы являются скалярными значениями (строки, int и т.д.). Третий формат немного неясен, поэтому в этом случае первый вариант, очевидно, будет работать лучше всего для вас.

Ответ 2

Эта проблема здесь:

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

Написание doRequest() на самом деле вызывает функцию. Вы хотите передать эту функцию:

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

Ответ 3

Вы неправильно понимаете функцию setTimeout.

Функция setTimeout выполняет функцию и выполняет ее позже.
Написав setTimeout(doRequest(url,proxys[proxy]), proxytimeout), вы вызываете функцию doRequest (сразу) и передаете результат (при условии, что он возвращает другую функцию) до setTimeout.

Вам нужно передать параметры doRequest в setTimeout, например:

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

Это передаст setTimeout сама функция doRequest (не вызывая ее сначала), а также передаст ей параметры, чтобы дать doRequest, когда он, наконец, называет его.