我有一些JavaScript代码,看起来像:
function statechangedPostQuestion()
{
//alert("statechangedPostQuestion");
if (xmlhttp.readyState==4)
{
var topicId = xmlhttp.responseText;
setTimeout("postinsql(topicId)",4000);
}
}
function postinsql(topicId)
{
//alert(topicId);
}
我得到一个错误,topicId没有定义
在我使用setTimeout()函数之前,一切都在工作。
我希望我的postinsql(topicId)函数在一段时间后被调用。
我该怎么办?
我知道这个问题已经问了10年了,但是,如果你一直滚动到这里,我认为你仍然面临着一些问题。Meder Omuraliev的解决方案是最简单的,可能对我们大多数人都有帮助,但对于那些不想有任何约束的人来说,下面是:
setTimeout使用Param
setTimeout(function(p){
//p == param1
},3000,param1);
使用立即调用的函数表达式
let param1 = 'demon';
setTimeout(function(p){
// p == 'demon'
},2000,(function(){
return param1;
})()
);
问题的解决方法
function statechangedPostQuestion()
{
//alert("statechangedPostQuestion");
if (xmlhttp.readyState==4)
{
setTimeout(postinsql,4000,(function(){
return xmlhttp.responseText;
})());
}
}
function postinsql(topicId)
{
//alert(topicId);
}
由于IE中的第三个可选参数有问题,并且使用闭包阻止我们改变变量(例如在循环中),但仍然达到预期的结果,我建议以下解决方案。
我们可以尝试像这样使用递归:
var i = 0;
var hellos = ["Hello World1!", "Hello World2!", "Hello World3!", "Hello World4!", "Hello World5!"];
if(hellos.length > 0) timeout();
function timeout() {
document.write('<p>' + hellos[i] + '<p>');
i++;
if (i < hellos.length)
setTimeout(timeout, 500);
}
我们需要确保没有其他东西改变这些变量,并且我们写了一个适当的递归条件来避免无限递归。
在做了一些研究和测试之后,唯一正确的实现是:
setTimeout(yourFunctionReference, 4000, param1, param2, paramN);
setTimeout将所有额外的参数传递给你的函数,以便在那里处理它们。
匿名函数可以用于非常基本的东西,但在一个对象的实例中,你必须使用“this”,没有办法使它工作。
任何匿名函数都会将“this”更改为指向窗口,因此您将失去对象引用。
有些答案是正确的,但令人费解。
四年后,我再次回答这个问题,因为我仍然会遇到过于复杂的代码来解决这个问题。有一个优雅的解决方案。
首先,在调用setTimeout时不要传入一个字符串作为第一个参数,因为它有效地调用了对缓慢的“eval”函数的调用。
那么如何将参数传递给超时函数呢?通过使用闭包:
settopic=function(topicid){
setTimeout(function(){
//thanks to closure, topicid is visible here
postinsql(topicid);
},4000);
}
...
if (xhr.readyState==4){
settopic(xhr.responseText);
}
一些人建议在调用timeout函数时使用匿名函数:
if (xhr.readyState==4){
setTimeout(function(){
settopic(xhr.responseText);
},4000);
}
语法是正确的。但是当settopic被调用时,也就是4秒之后,XHR对象可能就不一样了。因此,预绑定变量非常重要。
@Jiri Vetyska感谢你的帖子,但你的例子有问题。
我需要传递的目标是悬停(这)到一个超时函数,我尝试了你的方法。在IE9测试-不工作。
我也做了一些研究,这里指出的第三个参数是使用的脚本语言。没有提到额外的参数。
所以,我遵循@meder的答案,用这段代码解决了我的问题:
$('.targetItemClass').hover(ItemHoverIn, ItemHoverOut);
function ItemHoverIn() {
//some code here
}
function ItemHoverOut() {
var THIS = this;
setTimeout(
function () { ItemHoverOut_timeout(THIS); },
100
);
}
function ItemHoverOut_timeout(target) {
//do something with target which is hovered out
}
霍普,这对别人有用。