2011-09-15 155 views
3

我正在編寫谷歌瀏覽器擴展程序。我使用setTimeout來減慢對服務器的請求速度。但setTimeout不能按預期工作。它返回一個錯誤,說明沒有定義reqUrl。javascript setTimeout無法識別函數參數

基於對stackoverflow類似問題的答案,它似乎這是一個超出範圍的問題,我不明白如何解決它,除了使reqUrl一個全局變量,這似乎不是一個很好的解決方案。如果刪除括號,它就會失控,完全沒有時間延遲。

如何使這項工作?

這是代碼。儘管我認爲這不是問題的核心,但我已經列入了減速功能。

openDetailPg(profileLink[currentLink]); 
function openDetailPg(reqUrl) 
{ 
    console.log('openDetailPg at '+reqUrl); 
    setTimeout("createDetailWindow(reqUrl)",slowDown()); 
    ++sendCount; 
    timeOfLastRequest=new Date().getTime(); 
}; 
function createDetailWindow(detailUrl) 
{ 
    console.log('createDetailWindow'); 
    chrome.tabs.create({windowId: mainWindowId, url: detailUrl}, 
    function (tab) 
    { 
     console.log(' OpenDetailPg Created Tab '+tab.id+' with slow down of '+slowDown().toFixed(0)); 
     chrome.tabs.executeScript(tab.id, {file: 'profile.js'}); 
    }) 
}; 
function slowDown() 
{ 
    //console.log(' Slowdown: last interval '+ (new Date().getTime()-timeOfLastRequest)+' milisec.') 
    if (new Date().getTime()-timeOfLastRequest>minDelay) 
    { 
     console.log(' Previous Delay Greater Than Minimum Delay, Resetting Speed Count'); 
     sendCount=1; 
     timeOfFirstRequest=new Date().getTime(); //else forget about it, reset time of first request 
    } 
    elapsedTime=new Date().getTime()-timeOfFirstRequest; 
    avgSpeed = elapsedTime/sendCount; 
    //console.log(" Started @ "+timeOfFirstRequest+" Current time "+new Date().getTime()+" Avg time fr 1st HTTPRequest "+avgSpeed.toFixed(0)+' milisec over '+sendCount+' Req'); 
    if (avgSpeed<minDelay) 
    { 
     //console.log(" Delaying request by "+((minDelay-avgSpeed).toFixed(0))+" milisecs"); 
     return minDelay-avgSpeed; 
    } 
    else 
    { 
     //console.log(' No Delay on Request'); 
     return 1; 
    } 
}; 
+2

**未來建議**下一次提供最少的代碼量,以幫助您解決問題。你已經附加了太多的代碼。很多想嘗試幫助你的人可能會拒絕,因爲代碼量太多了(包括那些被註釋掉的日誌記錄調用)。 –

回答

0

你執行看起來像這樣的JavaScript的:createDetailWindow(reqUrl),這實際上不是你想要的東西 - you're試圖通過最初傳遞給openDetailPg字符串,對不對?因此,您傳遞給setTimeout的字符串需要適當構建:"createDetailWindow('" + reqUrl + "')"(假設reqUrl將始終正確轉義)。

順便說一句,這是最好的東西凝結下來的sscce,我花了一段時間只是爲了找到調用setTimeout

+1

(使用閉包的其他答案比我的要乾淨得多,比我的要乾淨得多。) –

+1

將字符串傳遞給'setTimeout'是相當過時的功能。 –

+0

因此我的後續評論。但是,我的實際解釋是爲什麼* OP看到錯誤。 –

3
function openDetailPg(reqUrl) 
{ 
    console.log('openDetailPg at '+reqUrl); 
    setTimeout(function(){createDetailWindow(reqUrl)},slowDown()); 
    ++sendCount; 
    timeOfLastRequest=new Date().getTime(); 
}; 
2

試試這樣說:

setTimeout(function() { createDetailWindow(reqUrl); }, slowDown()); 
2

試試這個:

setTimeout(function(){ createDetailWindow(reqUrl) },slowDown()); 
3

您需要使用匿名函數,該函數,例如:

setTimeout(function(){createDetailWindow(reqUrl)},slowDown()); 
+0

這工作得很好。謝謝。但爲什麼有必要在這裏使用匿名函數呢?我明白它解決了範圍問題,但我不明白爲什麼。 – Jerome

+0

有幾種方法可以做到這一點。第一個參數中的'setTimeout'函數需要函數或字符串的處理函數。如果傳遞字符串,它的作用與'eval'函數完全一樣,但是使用閉包,所以在該字符串中傳遞的變量是未定義的。當你傳遞簡單的處理程序'setTimeout'時調用該處理程序。而當你通過匿名函數'setTimeout'認爲你傳遞處理程序。閉包你可以在匿名函數中看到你的變量,如果之前聲明的話。但一般來說,你可以傳遞任何東西給匿名函數:'function(){var test = test2 + test3; for(var i = 0; i <5; i ++)...}'everything :) – antyrat

3

的setTimeout( {functionname},{timeout},{param1},{param2} ...)

例如

setTimeout(callMe, 1000, 'say','hello'); 
function callMe(p1, p2){ 
alert(p1+" "+p2); //alerts say hello 
} 
+0

This one worked!其他一些解決方案不起作用。 –