2010-01-10 31 views
14

这是我的问题。我有这个功能来测试代理服务器。为什么我的函数调用应该通过立即执行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'放置了一个任意值,它也没有任何作用。

回答

13

,该功能被执行,而不是传递给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); 

第二种格式是有点哈克,但工程仍如参数是标量值(字符串,整数等)。第三种格式有点不清楚,所以在这种情况下,第一种选择显然对你最有效。

+3

纠正我,如果我错了,但因为这是发生在一个循环内,你提供的第二种方法将无法正常工作。 'proxy'的值将会改变,因为没有创建闭包。 – nickf 2010-01-10 14:13:16

+0

@nickf:我正准备这么说。另外,第三个选项违反'eval是邪恶'。 – SLaks 2010-01-10 14:13:58

+0

@nickf,你是真的,我忽略了这一点。我已经更新了我的答案。 – 2010-01-10 14:28:04

0

这里这条线的问题是:

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

doRequest()实际上是调用函数。你需要的是通过本身的功能:当你给的功能,在形式的setTimeout

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

您误解了setTimeout函数。

setTimeout函数接受函数并稍后执行。
通过编写setTimeout(doRequest(url,proxys[proxy]), proxytimeout),您正在调用doRequest函数(立即),并将结果(假设它返回另一个函数)传递给setTimeout

你需要传递的doRequest参数setTimeout,像这样:

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

这将通过setTimeoutdoRequest功能本身(没有首先调用它),也将通过它的参数给当它最终调用它时。

相关问题