Reputation: 341
I have an array filled with function calls (i.e., func(param);
) like this:
var array = [
func(param),
func(param),
func(param)
];
At some later point, I want to invoke all of those function calls at once. How can I do that?
I know that you can run a function on each item in an array with a for loop or forEach like this:
for (var i = 0; i < 10; i++) {
// do stuff
}
Or
arrayName.forEach(function(e) {
// do stuff
});
But I'm not sure how to code this so that it will do the invoking?
I have tried what follows, but I get the error "arrayName[i] is not a function."
for (i = 0; i < arrayName.length; i++) {
arrayName[i]();
}
EDIT: THREE SOLUTIONS
Here is the basic code:
var soundsWaitingForNextBar = [];
while (soundsWaitingForNextBar.length > 0) {
soundsWaitingForNextBar[0](); // call first item in array
soundsWaitingForNextBar.shift(); // remove first item in array
}
Here is a more in depth version where items are pushed to the array every second but the array is only emptied every ten seconds:
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);
array[0]();
to call each array item/function.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
array.forEach(fn => fn());
to call each array item/function.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
Note: in the for loop that I originally used to remove items from the array with .splice
, I used array.length
. For example: for (let i = 0; i < array.length; i++)
. This didn't work (I'm not sure why) so I decided to determine the array length before the for loop using arrayLength = array.length;
. Now the program works as intended.
Upvotes: 0
Views: 948
Reputation: 18525
Your array is filled with results
of function calls
and not by functions
the way you have it setup now. What you want to it store a function (anonymous or not) and execute it in your for
loop.
You could also consider creating a function which to execute each of your functions and return an array with the results. For example you could Array.map through your array and since map returns an array as well you can have for each of your functions the actual result. Lets call the function invokeMap
(similar to the same exact function which lodash
has):
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)
Upvotes: 0
Reputation: 18973
You only need pass function name in array
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));
}
Upvotes: 1
Reputation: 44135
Because currently you're storing the return value of func(param)
. Make each item a function reference to be able to call it later:
var array = [
() => func(param),
() => func(param),
() => func(param)
];
Demo:
function func(p) {
console.log(p);
}
let param = "Parameter";
var array = [
() => func(param),
() => func(param),
() => func(param)
];
array.forEach(e => e());
Upvotes: 1
Reputation: 371233
With
var array = [
func(param),
func(param),
func(param)
];
you are already invoking those functions immediately, when the array is declared. It sounds like you want to defer their execution - you want them to be callable at some point in the future, not right now. instead, create an array of functions that, when called, call the function with the desired parameters, eg:
var array = [
() => func(param),
() => func(param),
() => func(param)
];
Then, your for
loop (or forEach
) will work:
for (let i = 0; i < array.length; i++) {
array[i]();
}
Demo:
const func = console.log;
const param = 'foo';
const array = [
() => func(param),
() => func(param),
() => func(param)
];
array.forEach(fn => fn());
You can also use .bind
instead of a higher-order function:
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());
Upvotes: 1