我有一些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)函数在一段时间后被调用。 我该怎么办?


当前回答

@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
}

霍普,这对别人有用。

其他回答

你可以将参数传递给setTimeout回调函数,如下所示:

setTimeout(函数,毫秒,param1, param2,…)

eg.

function myFunction() {
  setTimeout(alertMsg, 3000, "Hello");
}

function alertMsg(message) {
    alert(message)
}

David Meister的回答似乎考虑到了在调用setTimeout()之后、匿名函数调用之前可能立即改变的参数。但这太麻烦了,而且不太明显。我发现了一种优雅的方法,可以使用IIFE(立即调用的函数表达式)完成几乎相同的事情。

在下面的示例中,currentList变量被传递给IIFE, IIFE将其保存在闭包中,直到调用延迟函数。即使变量currentList在代码显示后立即改变,setInterval()也会做正确的事情。

如果没有这种IIFE技术,setTimeout()函数肯定会为DOM中的每个h2元素调用,但所有这些调用都只能看到最后一个h2元素的文本值。

<script>
  // Wait for the document to load.
  $(document).ready(function() {
  $("h2").each(function (index) {

    currentList = $(this).text();

    (function (param1, param2) {
        setTimeout(function() {
            $("span").text(param1 + ' : ' + param2 );
        }, param1 * 1000);

    })(index, currentList);
  });
</script>

在做了一些研究和测试之后,唯一正确的实现是:

setTimeout(yourFunctionReference, 4000, param1, param2, paramN);

setTimeout将所有额外的参数传递给你的函数,以便在那里处理它们。

匿名函数可以用于非常基本的东西,但在一个对象的实例中,你必须使用“this”,没有办法使它工作。 任何匿名函数都会将“this”更改为指向窗口,因此您将失去对象引用。

setTimeout(function() {
    postinsql(topicId);
}, 4000)

您需要将匿名函数作为参数而不是字符串提供,根据ECMAScript规范,后一种方法甚至不应该工作,但浏览器只是宽容。这是正确的解决方案,当使用setTimeout()或setInterval()时,不要依赖于传递字符串作为“函数”,它更慢,因为它必须被计算,这是不正确的。

更新:

正如Hobblin在他对问题的评论中所说,现在你可以使用function .prototype.bind()将参数传递给setTimeout内的函数。

例子:

setTimeout(postinsql.bind(null, topicId), 4000);

我知道这个问题已经问了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);
}