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


当前回答

用一个简单的带有两个参数的加法函数来回答这个问题。

var x = 3, y = 4;

setTimeout(function(arg1, arg2) { 
  return () => delayedSum(arg1, arg2);
}(x, y), 1000); 

function delayedSum(param1, param2) {
     alert(param1 + param2); // 7
}

其他回答

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>

//这是三个非常简单明了的答案:

function fun() {
    console.log(this.prop1, this.prop2, this.prop3);
}

let obj = { prop1: 'one', prop2: 'two', prop3: 'three' };

let bound = fun.bind(obj);

setTimeout(bound, 3000);

 // or

function funOut(par1, par2, par3) {

  return function() { 

    console.log(par1, par2, par3);

  }
};

setTimeout(funOut('one', 'two', 'three'), 5000);

 // or

let funny = function(a, b, c) { console.log(a, b, c); };

setTimeout(funny, 2000, 'hello', 'worldly', 'people');

在现代浏览器(ie IE11及以上)中,“setTimeout”接收第三个参数,该参数在计时器结束时作为参数发送给内部函数。

例子:

var hello = " hello World"; setTimeout(alert, 1000, hello);

更多的细节:

https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setTimeout http://arguments.callee.info/2008/11/10/passing-arguments-to-settimeout-and-setinterval/

支持setTimeout参数的最简单的跨浏览器解决方案:

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

如果你不介意不支持ie9及以下版本:

setTimeout(postinsql, 4000, topicId);

https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout

一般来说,如果需要将函数作为带有特定参数的回调函数传递,则可以使用高阶函数。这在ES6中是非常优雅的:

const someFunction = (params) => () => {
  //do whatever
};

setTimeout(someFunction(params), 1000);

或者如果someFunction是一阶的:

setTimeout(() => someFunction(params), 1000);