我有一些如下的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)函数。 我该怎么办?


#1楼

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

您需要将匿名函数作为参数而不是字符串作为参数,后一种方法甚至不符合ECMAScript规范,但浏览器比较宽松。 这是正确的解决方案,在使用setTimeout()setInterval() ,永远不要依赖于将字符串作为“函数”传递,它速度较慢,因为必须对其进行评估,而且这样做是不对的。

更新:

正如Hobblin在对问题的评论中所说,现在您可以使用Function.prototype.bind()将参数传递给setTimeout中的Function.prototype.bind()

例:

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

#2楼

更换

 setTimeout("postinsql(topicId)", 4000);

 setTimeout("postinsql(" + topicId + ")", 4000);

或更妙的是,用匿名函数替换字符串表达式

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

编辑:

Brownstone的注释不正确,这将按预期运行,如在Firebug控制台中运行该注释所展示的

(function() {function postinsql(id) {console.log(id);}var topicId = 3window.setTimeout("postinsql(" + topicId + ")",4000); // outputs 3 after 4 seconds
})();

请注意,我与其他人保持一致,您应该避免将字符串传递给setTimeout因为这将在字符串上调用eval()而不是传递一个函数。


#3楼

我想你要:

setTimeout("postinsql(" + topicId + ")", 4000);

#4楼

经过研究和测试之后,唯一正确的实现是:

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

setTimeout会将所有其他参数传递给您的函数,以便可以在此处对其进行处理。

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


#5楼

这是一个非常老的问题,答案已经是“正确的”,但我想我想提到的是这里没有人提及的另一种方法。 这是从出色的下划线库复制并粘贴的:

_.delay = function(func, wait) {var args = slice.call(arguments, 2);return setTimeout(function(){ return func.apply(null, args); }, wait);
};

您可以将任意数量的参数传递给setTimeout调用的函数, 并且作为附加的奖励(通常是奖励),调用setTimeout时,传递给函数的参数的值将被冻结,因此,如果它们改变了值在setTimeout()被调用和它超时之间的某个时间点,好吧...这不再那么令人沮丧了:)

这是一个小提琴 ,在这里您可以了解我的意思。


#6楼

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

希望这对其他人有用。


#7楼

霍布林(Hobblin)已经对这个问题发表了评论,但这确实是一个答案!

使用Function.prototype.bind()是最干净,最灵活的方法(具有设置this上下文的额外好处):

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

有关更多信息,请参见以下MDN链接:
https://developer.mozilla.org/en/docs/DOM/window.setTimeout#highlighter_547041 https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Function/bind#With_setTimeout


#8楼

我如何解决这个阶段?

就像这样:

setTimeout((function(_deepFunction ,_deepData){var _deepResultFunction = function _deepResultFunction(){_deepFunction(_deepData);};return _deepResultFunction;
})(fromOuterFunction, fromOuterData ) , 1000  );

setTimeout等待对函数的引用,因此我在一个闭包中创建了它,该闭包解释了我的数据并返回了一个包含我的数据实例的函数!

也许您可以改善这一部分:

_deepFunction(_deepData);// change to something like :
_deepFunction.apply(contextFromParams , args);

我在chrome,firefox和IE上测试了它,并且执行良好,我不了解性能,但是我需要它能正常工作。

样本测试:

myDelay_function = function(fn , params , ctxt , _time){
setTimeout((function(_deepFunction ,_deepData, _deepCtxt){var _deepResultFunction = function _deepResultFunction(){//_deepFunction(_deepData);_deepFunction.call(  _deepCtxt , _deepData);};return _deepResultFunction;})(fn , params , ctxt)
, _time)
};// the function to be used :
myFunc = function(param){ console.log(param + this.name) }
// note that we call this.name// a context object :
myObjet = {id : "myId" , name : "myName"
}// setting a parmeter
myParamter = "I am the outer parameter : ";//and now let's make the call :
myDelay_function(myFunc , myParamter  , myObjet , 1000)// this will produce this result on the console line :
// I am the outer parameter : myName

也许您可以更改签名以使其更加合规:

myNass_setTimeOut = function (fn , _time , params , ctxt ){
return setTimeout((function(_deepFunction ,_deepData, _deepCtxt){var _deepResultFunction = function _deepResultFunction(){//_deepFunction(_deepData);_deepFunction.apply(  _deepCtxt , _deepData);};return _deepResultFunction;})(fn , params , ctxt)
, _time)
};// and try again :
for(var i=0; i<10; i++){myNass_setTimeOut(console.log ,1000 , [i] , console)
}

最后回答原始问题:

 myNass_setTimeOut( postinsql, 4000, topicId );

希望能对您有所帮助!

ps:对不起,但英语不是我的母语!


#9楼

最近,我遇到了需要在循环中使用setTimeout的特殊情况。 了解这一点可以帮助您了解如何将参数传递给setTimeout

方法1

根据Sukima的建议 ,使用forEachObject.keys

var testObject = {prop1: 'test1',prop2: 'test2',prop3: 'test3'
};Object.keys(testObject).forEach(function(propertyName, i) {setTimeout(function() {console.log(testObject[propertyName]);}, i * 1000);
});

我推荐这种方法。

方法2

使用bind

var i = 0;
for (var propertyName in testObject) {setTimeout(function(propertyName) {console.log(testObject[propertyName]);}.bind(this, propertyName), i++ * 1000);
}

JSFiddle: http : //jsfiddle.net/MsBkW/

方法3

或者,如果您不能使用forEachbind ,请使用IIFE :

var i = 0;
for (var propertyName in testObject) {setTimeout((function(propertyName) {return function() {console.log(testObject[propertyName]);};})(propertyName), i++ * 1000);
}

方法4

但是,如果您不关心IE <10,则可以使用Fabio的建议 :

var i = 0;
for (var propertyName in testObject) {setTimeout(function(propertyName) {console.log(testObject[propertyName]);}, i++ * 1000, propertyName);
}

方法5(ES6)

使用块范围的变量:

let i = 0;
for (let propertyName in testObject) {setTimeout(() => console.log(testObject[propertyName]), i++ * 1000);
}

尽管我仍然建议在ES6中将Object.keysforEach使用。


#10楼

我知道它已经很老了,但我想在此添加我的(首选)口味。

我认为实现此目的的一种很topicId方法是将topicId传递给一个函数,该函数进而使用参数在内部引用主题ID。 即使topicId不久将更改外部的topicId ,此值也不会更改。

var topicId = xmlhttp.responseText;
var fDelayed = function(tid) {return function() {postinsql(tid);};
}
setTimeout(fDelayed(topicId),4000);

或简称:

var topicId = xmlhttp.responseText;
setTimeout(function(tid) {return function() { postinsql(tid); };
}(topicId), 4000);

#11楼

由于IE中的第三个optonal参数存在问题,并且使用闭包阻止我们更改变量(例如,在循环中)并仍然达到所需的结果,因此,我建议以下解决方案。

我们可以尝试像这样使用递归:

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);
}

我们需要确保没有其他改变这些变量,并确保编写适当的递归条件以避免无限递归。


#12楼

一些答案是正确的,但令人费解。

4年后,我再次回答这个问题,因为我仍然遇到过分复杂的代码来解决这个问题。 有一个优雅的解决方案。

首先,在调用setTimeout时不要将字符串作为第一个参数传递,因为它有效地调用了对慢速“ eval”函数的调用。

那么我们如何将参数传递给超时函数呢? 通过使用闭包:

settopic=function(topicid){setTimeout(function(){//thanks to closure, topicid is visible herepostinsql(topicid);},4000);
}...
if (xhr.readyState==4){settopic(xhr.responseText);
}

有些人建议在调用超时函数时使用匿名函数:

if (xhr.readyState==4){setTimeout(function(){settopic(xhr.responseText);},4000);
}

语法可行。 但是,在调用settopic的时间(即4秒钟后)时,XHR对象可能不相同。 因此, 预先绑定变量很重要。


#13楼

David Meister的答案似乎照顾到在调用setTimeout()之后但在调用匿名函数之前可能会立即更改的参数。 但这太麻烦而且不是很明显。 我发现了一种优雅的方法,可以使用IIFE(即称的函数表达式)来做几乎相同的事情。

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

如果没有这种IIFE技术,则肯定会为DOM中的每个h2元素调用setTimeout()函数,但是所有这些调用将仅看到最后一个 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>

#14楼

这适用于所有浏览器(IE是一个奇怪的球)

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

#15楼

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

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

如果您不介意不支持IE 9及更低版本:

setTimeout(postinsql, 4000, topicId);

https://developer.mozilla.org/zh-CN/docs/Web/API/WindowTimers/setTimeout


#16楼

我的答案:

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

说明:

创建的匿名函数将返回另一个匿名函数。 该函数可以访问最初传递的topicId ,因此不会出错。 立即调用第一个匿名函数,并传入topicId ,因此延迟注册的函数可以在调用时通过闭包访问topicId

要么

这基本上可以转换为:

setTimeout(function() {postinsql(topicId); // topicId inside higher scope (passed to returning function)
}, 4000);

编辑:我看到了相同的答案,所以看看他。 但是我没有偷他的答案! 我只是忘了看。 阅读说明,看看是否有助于理解代码。


#17楼

请注意,根据错误消息“ topicId”未定义的原因是,它在执行setTimeout时作为局部变量存在,而在对postinsql的延迟调用时不存在。 变量生存期尤其要注意,尤其是在尝试将“ this”作为对象引用传递时。

听说您可以将topicId作为第三个参数传递给setTimeout函数。 没有给出太多细节,但是我获得了足够的信息来使其工作,并且在Safari中成功了。 我不知道它们对“毫秒错误”的含义。 在这里查看:

http://www.howtocreate.co.uk/tutorials/javascript/timers


#18楼

通常,如果需要将函数作为带有特定参数的回调传递,则可以使用高阶函数。 ES6非常优雅:

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

或者,如果someFunction是一阶的:

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

#19楼

您可以尝试像这样的“ apply()”的默认功能,可以在数组中传递更多数量的参数作为您的要求

function postinsql(topicId)
{//alert(topicId);
}
setTimeout(postinsql.apply(window,["mytopic"])
,500);

#20楼

如果您想将变量作为参数传递,请尝试以下操作

如果要求是功能和var作为帕尔马然后尝试这个

setTimeout((param1,param2) => { alert(param1 + param2);postinsql(topicId);
},2000,'msg1', 'msg2')

如果需求仅是变量作为参数,则尝试此

 setTimeout((param1,param2) => { alert(param1 + param2) },2000,'msg1', 'msg2') 

您可以在ES5和ES6上尝试


#21楼

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

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);// orfunction funOut(par1, par2, par3) {return function() { console.log(par1, par2, par3);}
};setTimeout(funOut('one', 'two', 'three'), 5000);// orlet funny = function(a, b, c) { console.log(a, b, c); };setTimeout(funny, 2000, 'hello', 'worldly', 'people');

#22楼

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

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);// orfunction funOut(par1, par2, par3) {return function() { console.log(par1, par2, par3);}
};setTimeout(funOut('one', 'two', 'three'), 5000);// orlet funny = function(a, b, c) { console.log(a, b, c); };setTimeout(funny, 2000, 'hello', 'worldly', 'people');

#23楼

您可以通过以下方式将参数传递给setTimeout回调函数:

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

例如。

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

#24楼

setTimeout是WHAT WG定义的DOM的一部分。

https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html

您想要的方法是:

handle = self.setTimeout( handler [, timeout [, arguments... ] ] )

安排超时时间,以在超时毫秒后运行处理程序。 任何参数都直接传递给处理程序。

setTimeout(postinsql, 4000, topicId);

显然,IE10支持额外的参数。 或者,您可以使用setTimeout(postinsql.bind(null, topicId), 4000); ,但是传递额外的参数会更简单,这是可取的。

历史事实:在VBScript时代,在JScript中,setTimeout的第三个参数是语言,为字符串,默认为“ JScript”,但可以选择使用“ VBScript”。 https://docs.microsoft.com/zh-cn/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741500(v%3Dvs.85)


#25楼

在现代浏览器中,“ setTimeout”接收第三个参数,该参数在计时器结束时作为参数发送到内部函数。

例:

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

更多细节:

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

如何将参数传递给setTimeout()回调?相关推荐

  1. 如何将命令行参数传递给Node.js程序?

    我有一个用Node.js编写的Web服务器,我想使用一个特定的文件夹启动. 我不确定如何在JavaScript中访问参数. 我正在像这样运行节点: $ node server.js folder 这是 ...

  2. 通过BeanShell获取UUID并将参数传递给Jmeter

    有些HTTPS请求报文的报文体中包含由客户端生成的UUID,在用Jmeter做接口自动化测试的时候,因为越过了客户端,直接向服务器端发送报文,所以,需要在Jmeter中通过beanshell获取UUI ...

  3. java+hadoop配置参数_将Hadoop参数传递给Java代码

    我有一个Uber jar执行一些级联ETL任务. jar的执行方式如下: hadoop jar munge-data.jar 我希望在作业启动时将参数传递给jar,例如 hadoop jar mung ...

  4. php向bat中传递参数,php-将参数传递给PHPUnit

    php-将参数传递给PHPUnit 我开始编写PHPUnit测试,并且希望这些测试可以在开发人员的机器以及我们的服务器上运行. 开发人员计算机的设置与服务器不同,甚至彼此不同. 要在这些不同的地方运行 ...

  5. jsf 后台参数到页面_JSF:直接从页面将参数传递给JSF操作方法,这是JavaEE 6+的一个不错的功能...

    jsf 后台参数到页面 其中一个JSF 2+不错的特点出现在Java企业版的JavaEE 6 +,是你可以传递参数给喜欢的commandButton和commandLink组件的任何动作元件操作方法. ...

  6. JSF:直接从页面将参数传递给JSF操作方法,这是JavaEE 6+的一个不错的功能

    Java企业版JavaEE 6+中提供的JSF 2+的一项不错的功能是,您可以将参数传递给任何操作组件(例如commandButton或commandLink组件)的操作方法. 基于此,您可以最大程度 ...

  7. java变量传递给asp,我应该如何将多个参数传递给ASP.Net Web API GET?

    回答(10) 2 years ago 这个记录标记是什么意思?如果这仅用于记录目的,我将使用GET并禁用所有缓存,因为您要记录此资源的每个查询 . 如果记录标记有另一个目的,POST就是要走的路 . ...

  8. plsql 往视图传参数_我们可以将参数传递给SQL中的视图吗?

    20 个答案: 答案 0 :(得分:113) 如前所述,你做不到. 可能的解决方案是实现存储的函数,例如: CREATE FUNCTION v_emp (@pintEno INT) RETURNS T ...

  9. 将参数传递给Bash函数

    我试图搜索如何在Bash函数中传递参数,但是出现的是如何从命令行传递参数. 我想在我的脚本中传递参数. 我试过了: myBackupFunction("..", "... ...

最新文章

  1. 总结 20 个开发细节
  2. win7下安装dynamips完全版
  3. 对话式AI 2019年遇来的新市场
  4. ap计算机科学换学分,科普:AP成绩出来了 换学分最全指南就在这
  5. 远程桌面Web连接访问及端口更改方法
  6. Feed43自定义 RSS 订阅源
  7. C++实现坐标的平移和旋转
  8. map怎么转化dto_java实现Object和Map之间的转换3种方式
  9. jsp mysql 判断连接数据库失败 try_急……jsp 连接mysql不知道哪里出异常
  10. Java 8 HashMap键与Comparable接口
  11. java dct变换_Discrete Cosine Transform [DCT] (离散余弦变换)
  12. Springboot2学习博客
  13. [转]Vmware ESX 4上虚拟机 Redhat 5.2(CentOS 5.2)启动在Starting udev 停几个小时
  14. 通用知识图谱的构建及在QQ浏览器的应用实践
  15. mysql判断不为null
  16. ListUtil常用操作
  17. 记一次消息总线的打造 - McKay - 博客园
  18. 屏幕滑动_小米滑盖式可折叠手机渲染图曝光,屏幕不仅可以折叠还可滑动
  19. 武汉年会签到,抽奖,摇一摇,微信上墙,互动大屏
  20. vs2003远程调试总结

热门文章

  1. linux环境知识点备忘录
  2. linux 静态路由修改
  3. Java NIO SocketChannel+Buffer+Selector 详解(含多人聊天室实例)
  4. Java常用api和操作必背
  5. spring 整合struts
  6. [转]JAVA 在main中访问内部类、方法等
  7. java 访问权限控制
  8. IRF配置(LACP MAD检测方式)
  9. Linux中,Mysql安装
  10. 比较两个sheet页中的内容,自动切换