2011-09-15 138 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!其他一些解决方案不起作用。 –