【问题标题】:use apply() to execute array of setTimeouts with args使用 apply() 执行带有 args 的 setTimeouts 数组
【发布时间】:2016-04-03 11:37:11
【问题描述】:

我需要能够构建一组匿名函数,这些函数使用每个函数的唯一参数执行 setTimeout。以下代码已经在 SO 上提出并运行,但它只处理 setTimeout 的立即执行。它没有解释如何将一组 setTimeout 函数累积到一个数组中,每个 setTimeout 函数都有自己的闭包,该闭包定义了一个用于执行 setTimeout 的唯一变量。

这是 SO 上已经存在的内容:

var strings = [ "hello", "world" ];
for(var i=0;i<strings.length;i++) {
    setTimeout(
        (function(s) {
            return function() {
                alert(s);
            }
        })(strings[i]), 1000);
}

这是我尝试过的众多排列之一:

var strings = [ "hello", "world" ];
var func_array = [];
for (var i=0; i < strings.length; i++) {
    func_array.push(function() {
      setTimeout(
          (function(s) {
              return function() {
                  alert(s);
              }
          })(strings[i]), 1000);
    });
}

当在 func_array 上调用 apply() 时,每个调用的 strings[i] 值都是相同的,即字符串数组的最后一个成员。

另一个尝试:这里我们让被推送到 func_array 的函数自动执行,以便正确地限定 strings[i] 变量的范围。但是,apply() 只能看到“未定义”,因为该函数已经执行。

var strings = [ "hello", "world" ];
var func_array = [];
for (var i=0; i < strings.length; i++) {
    func_array.push(function(s) {
      setTimeout(
          (function(s) {
              return function() {
                  alert(s);
              }
          })(s), 1000);
    }(strings[i]));
}

想法?

【问题讨论】:

    标签: javascript closures settimeout


    【解决方案1】:

    使用Function.prototype.bind()。它变得比实际简单得多。

    var strings = [ "hello", "world" ];
    var func_array = [];
    for (var i=0; i < strings.length; i++) {
        var fn = function(string){
            return setTimeout(function(){ alert(string) } ,1000);
        };
        func_array.push(fn.bind(this, strings[i]));
    }
    

    【讨论】:

    • 这解决了这个问题。漂亮、干净、纯粹的 JS。谢谢!
    【解决方案2】:

    这就是你想要的。

    var strings = ["hello", "world"];
    var func_array = [];
    for (var i = 0; i < strings.length; i++) {
        (function (s) {
            var func = function () {
                alert("String is " + s);
            }
            
            var futureFunc = function () {
                setTimeout(func, 1000);
            }
            
            func_array.push(futureFunc);
        } (strings[i]));
    }
    
    func_array[0]()
    func_array[1]()

    【讨论】:

    • 它有效。你的和 jkris 的答案都可以完成这项工作。您选择哪一个取决于编码风格以及它如何适合您可能正在使用的应用程序。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-09-14
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-27
    • 1970-01-01
    相关资源
    最近更新 更多