Javascript 带参数的 setTimeout
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12451844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
setTimeout with arguments
提问by Menztrual
having a bit of a headache on trying to work this out. What I want to do is have a custom setTimeout with arguments with outhaving to create a function to pass it. Let me explain by code:
试图解决这个问题有点头疼。我想要做的是有一个带有参数的自定义 setTimeout ,而不必创建一个函数来传递它。我用代码解释一下:
Want to avoid:
想要避免:
function makeTimeout(serial){
serial.close();
}
setTimeout(makeTimeout(sp.name), 250);
what I want to do is somehow just call a 1 liner by like:
我想要做的就是以某种方式通过以下方式调用 1 班轮:
setTimeout(function(arg1){ .... }(argument_value), 250);
Can this be done or can you only pass in a no argument function?
这可以完成还是只能传入无参数函数?
回答by Jo?o Silva
You can pass it an anonymous function that invokes makeTimeout
with the given arguments:
您可以向它传递一个匿名函数,makeTimeout
该函数使用给定的参数进行调用:
setTimeout(function () {
makeTimeout(sp.name);
}, 250);
There's also an alternative, using bind
:
还有一种替代方法,使用bind
:
setTimeout(makeTimeout.bind(this, sp.name), 250);
This function, however, is an ECMAScript 5th Edition feature, not yet supported in all major browsers. For compatibility, you can include bind
's source, which is available at MDN, allowing you to use it in browsers that don't support it natively.
然而,这个函数是 ECMAScript 第 5 版的一个特性,并不是所有主流浏览器都支持。为了兼容性,您可以包含MDN 上提供的includebind
的source,允许您在本机不支持它的浏览器中使用它。
DEMO.
演示。
回答by RobG
If you don't want to declare a separate function, you can use an immediately invoked function expression and closure, e.g.
如果不想声明单独的函数,可以使用立即调用的函数表达式和闭包,例如
// Parameter to use
var bar = 'bar';
// Function to call
function foo(arg) {
alert(arg);
}
// Go…
setTimeout(
(function(arg1){
return function(){
foo(arg1);
};
}(bar)), 2000);
Alternatively, you can use the function constructor:
或者,您可以使用函数构造函数:
setTimeout( Function('foo(bar)'), 2000);
Or you can use a string:
或者您可以使用字符串:
setTimeout('foo(bar)', 1000);
which is essentially the same thing. Now wait for howls of "but that's like using eval, and everyone knows eval is evil and a massive security breach — all your firstborn are doomed!"
这本质上是一样的。现在等待“但那就像使用 eval 一样,每个人都知道 eval 是邪恶的并且是一个巨大的安全漏洞——你所有的长子都注定要失败!”
But seriously, eval
(and the Function constructor) are inefficient and can lead to lazy programming, so use another option, such as the first above.
但严重的是,eval
(和 Function 构造函数)效率低下,可能导致惰性编程,因此请使用另一个选项,例如上面的第一个。
回答by unsynchronized
It appears the ability has been added to some browsers pass parameters to setTimeout:
似乎该功能已添加到某些浏览器中,将参数传递给 setTimeout:
syntax:setTimeout (function (p1,p2) {},1000,p1,p2);
(add as many params as you want)
语法:(setTimeout (function (p1,p2) {},1000,p1,p2);
添加任意数量的参数)
If you want to ensure it works everywhere, you can use the attached code.
如果你想确保它在任何地方都能工作,你可以使用附加的代码。
Note:If you want to set a timeout immediately after installing it, it's best to use the callback parameter and do it in there
注意:如果你想在安装后立即设置超时,最好使用回调参数并在那里进行
for example
例如
installSwizzledTimeout(function(param1,param2){
setTimeout(myFunc,200,param1,param2);},param1,param2);
}
This is because it uses a trick to detect if it is needed, by setting a very short timeout and counting the parameters.
这是因为它使用了一种技巧来检测是否需要它,通过设置一个非常短的超时并计算参数。
window.swizzledSetTimeout = function (fn, ms) {
if (arguments.length === 2) {
//console.log("Bypassing swizzledSetTimeout");
return window.originalSetTimeout(fn, ms);
} else {
var args = [];
for (i = 2; i < arguments.length; i++) {
args.push(arguments[i])
};
//console.log("Setting swizzledSetTimeout for function (",args,") {...} in ",ms," msec");
var retval = window.originalSetTimeout(function () {
//console.log("Invoking swizzledSetTimeout for function (",args,") {...}");
fn.apply(null, args);
}, ms);
return retval;
}
}
function installSwizzledTimeout(cb) {
var args = [];
for (i = 1; i < arguments.length; i++) {
args.push(arguments[i])
};
setTimeout(function (arg) {
//console.log("arguments.length:",arguments.length,window.setTimeout.toString());
if (arguments.length == 0) {
function doInstall() {
//console.log("Installing new setTimeout");
window.originalSetTimeout = window.setTimeout;
window.setTimeout = function setTimeout() {
return window.swizzledSetTimeout.apply(null, arguments);
};
if (cb) {
cb.apply(null, args);
};
}
if (window.setTimeout.toString().indexOf("swizzledSetTimeout") < 0) {
doInstall();
}
} else {
//console.log("existing set time supports arguments ");
if (cb) {
cb.apply(null, args);
};
}
}, 0, 1, 2, 3, 4);
}
回答by N00BEST
I had a method that needed a constant timeout setting also having parameters to the final executed function, so I did as follow using anonymous functions:
我有一个方法需要一个恒定的超时设置,也有最终执行函数的参数,所以我使用匿名函数执行以下操作:
function checkPageLoaded(checker, callback, nextCallTime) {
return () => {
let checkoutLoader = document.querySelector(checker);
if(checkoutLoader === null)
callback();
else
setTimeout(checkPageLoaded(checker, callback, nextCallTime), nextCallTime);
}
}
and then just call it as follows:
然后按如下方式调用它:
setTimeout(checkPageLoaded('.loader', reloadPagination, 500), 500);
This way the desired function to be executing with the arguments will be the one defined as an anonymous one.
这样,要使用参数执行的所需函数将是定义为匿名函数的函数。