将函数推入数组 - 循环遍历并切割?

10
使用Javascript,我需要能够做到以下几点:
1. 将相同的函数(每个函数的参数不同)推入一个数组中。 2. 然后依次运行每个函数(例如,仅弹出参数/数字的警报)。 3. 在每个函数运行后,我需要能够将该函数从数组中删除。 4. 每次都要检查数组长度 - 一旦数组再次为空,则向用户发出“完成”警报。
现在,我似乎能够完成任务1、2和4,但我不知道如何从数组中剔除已经运行过的函数 - 有谁可以帮忙吗?由于我无法删除函数,因此一旦调用了所有函数,我就永远得不到“完成”警报。
我的Javascript代码如下:
// Create empty array
var array = [];

// Push functions into array - dynamic amount and could be any amount of functions
array.push(func(1));
array.push(func(2));
array.push(func(3));

// Call array manager function after pushing array
arrayManager();

// Array manager function to splice and detect when finished
function arrayManager() {
    if (array.length < 1) {
        alert("done");
    }
    else {
    //////////////////////////////////
    // << THIS IS WHERE I DON'T KNOW HOW TO SPLICE THE ITEM FROM THE ARRAY
    //////////////////////////////////
    }
}

// Function for array objects - alert passed parameter
function func(num){
    alert(num);
}

你究竟想要实现什么目标?可能有更直接的方法来完成它。 - zero
1
你读过splice文档了吗? - chrisfrancis27
同时,“length”属性从1开始而不是零。 - zero
@zero 如果数组中没有任何项目怎么办? - chrisfrancis27
2
现在,您没有将任何函数推送到数组中。 - I Hate Lazy
5个回答

20

首先,目前你并没有将函数推入数组中,而是执行了这个函数。为了实现推入操作,你的函数应该像这样:

// Function for array objects - alert passed parameter
function func(num){
  return function(){
    alert(num);
  }
}
现在,如果你的函数是同步的,你可以简单地遍历数组。
for(var i in arr){
  arr[i]();
}
console.log('done');

如果我们处理异步函数,那么它们需要有一个回调函数:

// Function for array objects - alert passed parameter
function func(num){
  return function(callback){
    alert(num);
    callback();
  }
}

然后您可以使用计数器并行运行。

var count = arr.length;
for(var i in arr){
  arr[i](function(){
    if(--count === 0){
      console.log('Done');
    }
  });
}

或者按顺序:

function run(){
  var fn = arr.shift();
  if(!fn){
    console.log('Done');
  } else {
    fn(run);
  }
}
run();

谢谢你的回答!当然,异步迭代需要调用fn(run()),否则它将在第一个“run”之后停止(双关语)。如果我漏掉了什么,请告诉我我错在哪里。:D - DBrown

2
这应该能够满足你的需求:

这段代码可以完成你所需要的功能:

var next_func = array.splice(0, 1)[0]

"splice"至少需要两个参数:第一个是要开始删除的索引,第二个是要删除的项目数。由于它返回一个新数组,如果只想获取函数,则可以从splice中获取第一个值。您还可以在这两个参数之后添加任意数量的值; 这些将替换您删除的内容而添加到数组中。
然而,我很好奇为什么您会这样做 - 尽管我可以理解以非传统方式进行某些操作作为一种智力锻炼,但如果您是编程新手,我认为有更好的方法来完成此操作。在使用数组函数时,没有特定的需要从数组中删除项目。对我而言,先从数组中执行每个函数,然后在完成循环后设置“array = []”更有意义。但是,根据情况,这仍然可能是您正在做的最佳方法,我只是想提供一些思考的食物。"

我对JavaScript(以及编码总体而言)非常陌生,所以如果我的某些方法看起来很奇怪或者有更简单的方法,请原谅。基本上,我在Titanium Appcelerator中使用纯JavaScript开发移动应用程序 - 在整个应用程序中,用户将绘制涂鸦或素描,最后我需要能够上传所有创建的涂鸦到服务器。我想要实现这个功能的想法是将每个涂鸦作为一个函数添加到数组中,循环遍历该数组并上传,直到它为空,在它为空时允许他们继续 - 如果这有意义的话? - Lauren Reynolds
2
在表面上看起来相当合理。然而,如果您一次卸载所有函数,实际上没有必要费心进行拼接。像这种情况下使用拼接的主要优点是,如果您以某种随机的方式执行函数。如果您计划同时执行它们所有,我会使用for循环遍历并执行每个函数,然后在完成后将数组设置为空。此外,如果您对JavaScript不熟悉,请务必查看Chris Francis提供的MDN资源-这是学习JavaScript的一个很好的途径。 - Bubbles

2
// Create empty array
var array = [];

// Push functions into array - dynamic amount and could be any amount of functions
array.push(function() { func(1); });
//if you call array.push(func(1)) the function is executed immediatly
//then null is stored in the array
array.push(function() { func(2); });
array.push(function() { func(3); });

// Call array manager function after pushing array
arrayManager();

// Array manager function to splice and detect when finished
function arrayManager() {
    while (array.length){
        var fnc=array.splice(0,1)[0]
        fnc();
    }
    alert ("done");            
}

// Function for array objects - alert passed parameter
function func(num){
    alert(num);
}​

2

这是你需要的吗?

1:将一定数量的相同函数(每个函数的参数不同)推入数组中。

function func(num){
    alert(num);
}

var k = [];
k.push({f:func, params:[1]});
k.push({f:func, params:[2]});
k.push({f:func, params:[3]});

2: 然后逐个运行每个函数(对于此示例,只需警告参数/数字)

3: 每次运行完函数后,我需要能够从数组中将该函数切出

4: 每次检查数组长度 - 一旦数组再次为空 - 警告用户已完成

while (k.length > 0) {
 k[0].f(k[0].params);
 k.shift();
}
alert("done");

2

http://jsfiddle.net/nZ459/1/

如果您想以您目前的方式推送每个带有其参数的函数,您需要这样包装该函数:
function wrapper(arg){
    return function(){
        console.log(arg);
    };
}


var ar = [];

console.log("pushing functions");

ar.push(wrapper(1));
ar.push(wrapper(2));
ar.push(wrapper('three'));

console.log("done pushing functions");

while (ar.length){
    var fn = ar.shift();
    console.log("calling ", fn);
    fn();
}

或者,您可以创建一个通用的包装器,它以函数和参数作为参数,并返回一个匿名函数。

更直接地回答您的问题,按照您所需的方式运行数组的最简单方法如下:

while (array.length){
    var item = array.shift();
    ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接