【问题标题】:How to invoke every array item when each array item is a function call当每个数组项都是函数调用时如何调用每个数组项
【发布时间】:2019-06-22 03:58:56
【问题描述】:

我有一个充满函数调用(即func(param);)的数组,如下所示:

var array = [
  func(param),
  func(param),
  func(param)
];

稍后,我想一次调用所有这些函数调用。我该怎么做?

我知道您可以使用 for 循环或 forEach 对数组中的每个项目运行一个函数,如下所示:

for (var i = 0; i < 10; i++) {
  // do stuff
}

或者

arrayName.forEach(function(e) {
  // do stuff
});

但我不确定如何编写代码以便它执行调用?

我已经尝试了以下操作,但我收到错误“arrayName[i] 不是函数。”

for (i = 0; i < arrayName.length; i++) {
  arrayName[i]();
}

编辑:三种解决方案

1:最好,使用 while 循环

这是基本代码:

var soundsWaitingForNextBar = [];

while (soundsWaitingForNextBar.length > 0) {
  soundsWaitingForNextBar[0](); // call first item in array
  soundsWaitingForNextBar.shift(); // remove first item in array
}

这是一个更深入的版本,其中项目每秒被推送到数组,但数组仅每 10 秒清空一次:

var soundsWaitingForNextBar = [];

function foo() {
  console.log('')
} // just making sure foo is a function

// pusing some functions into the array
soundsWaitingForNextBar.push(() => foo());
soundsWaitingForNextBar.push(() => foo());

setInterval(function() { // pushing items to array periodically to make sure the while loop is only emptying when it is called by setInterval and not every time an item is added to the array
  soundsWaitingForNextBar.push(() => foo());
}, 2000);


setInterval(function() {
  // this while loop does the magic: it calls and removes each item in the array
  while (soundsWaitingForNextBar.length > 0) {
    soundsWaitingForNextBar[0](); // call first item in array
    soundsWaitingForNextBar.shift(); // remove first item in array
  }
}, 10000);

setInterval(function() { // just checking to see how/when items are added to the array and emptied
  console.log('array.length: ' + soundsWaitingForNextBar.length);
}, 1000);

2:使用array[0](); 调用每个数组项/函数。

const func = console.log;
const param = 'foo';

const array = [
  () => func(param),
  () => func(param),
  () => func(param)
];

console.log(array.length); // just noting the original array length

arrayLength = array.length;
for (let i = 0; i < arrayLength; i++) {
  array[0]();
  array.shift();
}

console.log(array.length); // just making sure the array is empty

3:使用array.forEach(fn =&gt; fn()); 调用每个数组项/函数。

const func = console.log;
const param = 'foo';

const array = [
  () => func(param),
  () => func(param),
  () => func(param)
];

console.log(array.length); // just noting the original array length

array.forEach(fn => fn()); // calls each array item/function

arrayLength = array.length;
for (let i = 0; i < arrayLength; i++) {
  array.shift();
}

console.log(array.length); // just making sure the array is empty

注意:在我最初使用.splice 从数组中删除项目的for 循环中,我使用了array.length。例如:for (let i = 0; i &lt; array.length; i++)。这不起作用(我不确定为什么)所以我决定在 for 循环之前使用arrayLength = array.length; 确定数组长度。现在程序按预期运行。

【问题讨论】:

    标签: javascript arrays function for-loop foreach


    【解决方案1】:

    你只需要在数组中传递函数名

    var arrayName = [
      func,
      func,
      func
    ];
    

    function func(a){
    return a*2;
    };
    var arrayName = [
      func,
      func,
      func
    ];
    
    for (i = 0; i < arrayName.length; i++) {
      console.log(arrayName[i](2));
    }

    【讨论】:

      【解决方案2】:

      var array = [
        func(param),
        func(param),
        func(param)
      ];
      

      已经在声明数组时立即调用这些函数。听起来您想推迟它们的执行 - 您希望它们在将来的某个时间可以调用,而不是现在。相反,创建一个函数数组,当被调用时,使用所需的参数调用函数,例如:

      var array = [
        () => func(param),
        () => func(param),
        () => func(param)
      ];
      

      然后,您的for 循环(或forEach)将起作用:

      for (let i = 0; i < array.length; i++) {
        array[i]();
      }
      

      演示:

      const func = console.log;
      const param = 'foo';
      
      const array = [
        () => func(param),
        () => func(param),
        () => func(param)
      ];
      array.forEach(fn => fn());

      您也可以使用.bind 代替高阶函数:

      const func = console.log;
      const param = 'foo';
      
      const array = [
        func.bind(undefined, param),
        func.bind(undefined, param),
        func.bind(undefined, param)
      ];
      array.forEach(fn => fn());

      【讨论】:

      • 太棒了。我会试一试并报告!
      • 你的回答对我来说是最清楚的。我确实遇到了一个新问题,我在“编辑”下的帖子中概述了你的方法。我很想知道你对此有什么想法吗?
      • 对数组进行迭代时,是否要调用并移除迭代过程中添加的项?
      • 主要目标是两部分。我想要 1. 调用数组中的所有项目,然后 2. 从数组中删除所有被调用的项目(因此下次发生此过程时不会再次调用它们)。每个操作(调用,删除)都可以单独完成,但我认为逐个调用和删除每个项目而不是调用每个项目然后删除每个项目会更聪明。如果在此过程发生时添加了新项目,则如果可能,这次不应调用它们。但我认为这是我以后可以处理的问题。
      • 我想我找到了两个解决方案。我很想知道你是否喜欢它们?我把它们贴在上面。我不确定在 for 循环正在调用然后删除数组项的过程中是否可以将新项添加到我的程序中,但我还没有遇到问题。
      【解决方案3】:

      因为当前您正在存储func(param) 的返回值。使每个项目成为函数引用,以便以后能够调用它:

      var array = [
        () => func(param),
        () => func(param),
        () => func(param)
      ];
      

      演示:

      function func(p) {
        console.log(p);
      }
      
      let param = "Parameter";
      
      var array = [
        () => func(param),
        () => func(param),
        () => func(param)
      ];
      
      array.forEach(e => e());

      【讨论】:

        【解决方案4】:

        您的数组填充了resultsfunction calls,而不是您现在设置的functions。你想要它存储一个函数(匿名与否)并在你的for循环中执行它。

        您还可以考虑创建一个函数来执行您的每个函数并返回一个包含结果的数组。例如,您可以 Array.map 通过您的数组,并且由于 map 也返回一个数组,您可以为每个函数获取实际结果。让我们调用函数invokeMap(类似于lodashsame exact function):

        let add2 = x => x + 2
        
        var fnArray = [  // array of anonymous functions
          (x) => x,  
          (x) => add2(x),
          (x) => add2(x) + add2(x)
        ];
        
        let invokeMap = (arr, ...parrams) => arr.map((fn => fn(...parrams)))
         
        let result = invokeMap(fnArray, 1) // pass one as a parameter to all functions
        
        console.log(result)

        【讨论】:

          猜你喜欢
          • 2022-01-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多