2010-01-10 47 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功能本身(沒有首先調用它),也將通過它的參數給當它最終調用它時。

相關問題