带参数的setTimeout

时间:2012-09-17 00:25:28

标签: javascript

试图解决这个问题时有点头疼。我想要做的是有一个自定义的setTimeout,参数没有必须创建一个函数来传递它。让我用代码解释一下:

想要避免:

function makeTimeout(serial){
  serial.close();
}

setTimeout(makeTimeout(sp.name), 250);

我想要做的就是以某种方式通过以下方式调用1个班轮:

setTimeout(function(arg1){ .... }(argument_value), 250);

可以这样做,还是只能传递一个无参数函数?

4 个答案:

答案 0 :(得分:23)

您可以向它传递一个匿名函数,该函数使用给定的参数调用makeTimeout

setTimeout(function () {
  makeTimeout(sp.name);
}, 250);

还有另一种选择,使用bind

setTimeout(makeTimeout.bind(this, sp.name), 250);

但是,此功能是ECMAScript第5版功能,尚未在所有主流浏览器中支持。为了兼容性,您可以添加bind的{​​{3}},它可以在MDN上使用,允许您在本机不支持它的浏览器中使用它。

<强> source

答案 1 :(得分:4)

如果你不想声明一个单独的函数,你可以使用一个立即调用的函数表达式和闭包,例如。

// Parameter to use
var bar = 'bar';

// Function to call
function foo(arg) {
  alert(arg);
}

// Go…
setTimeout(
  (function(arg1){
    return function(){
      foo(arg1);
    };
  }(bar)), 2000);

或者,您可以使用函数构造函数:

setTimeout( Function('foo(bar)'), 2000);

或者您可以使用字符串:

setTimeout('foo(bar)', 1000);

这基本上是一回事。现在等待“的嚎叫,但这就像使用eval,每个人都知道eval是邪恶的,并且是一次巨大的安全漏洞 - 你所有的长子都注定要失败!

但严重的是,eval(以及Function构造函数)效率低下并且可能导致延迟编程,因此请使用其他选项,例如上面的第一个选项。

答案 2 :(得分:3)

似乎已将该功能添加到某些浏览器将参数传递给setTimeout:

语法: setTimeout (function (p1,p2) {},1000,p1,p2); (根据需要添加任意数量的参数)

如果您想确保它可以在任何地方使用,您可以使用附加的代码。

注意:如果你想在安装后立即设置超时,最好使用callback参数并在那里进行

例如

installSwizzledTimeout(function(param1,param2){
    setTimeout(myFunc,200,param1,param2);},param1,param2);
}

这是因为它通过设置非常短的超时和计算参数来使用技巧来检测是否需要它。

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

答案 3 :(得分:0)

我有一个需要恒定超时设置的方法,该方法还具有最终执行函数的参数,因此我使用匿名函数按如下进行操作:

I am producer: I now put task
buffer[]: [ 0 , 0 ,]
I am producer: I now put task
buffer[]: [ 0 , 1 ,]
buffer[use_ptr]: 0
I am consumer:2, I have done a task
buffer[use_ptr]: 1
I am consumer:2, I have done a task
I am producer: I now put task
buffer[]: [ 2 , 1 ,]
I am producer: I now put task
buffer[]: [ 2 , 3 ,]
buffer[use_ptr]: 2
I am consumer:2, I have done a task
buffer[use_ptr]: 3
I am consumer:2, I have done a task
I am producer: I now put task
buffer[]: [ 4 , 3 ,]
I am producer: I quit now
producer ended
 waiting for consumers to end
buffer[use_ptr]: 4
I am consumer:2, I have done a task

,然后按如下所示进行调用:

function checkPageLoaded(checker, callback, nextCallTime) {
    return () => {
        let checkoutLoader = document.querySelector(checker);
        if(checkoutLoader === null)
            callback();
        else
            setTimeout(checkPageLoaded(checker, callback, nextCallTime), nextCallTime);
    }
}

这样,用参数执行的所需函数将是定义为匿名函数的函数。