A function that counts how often it calls another function

I have a function "twice" that returns 2 arguments passed into it. I also have another function "runTwice" that counts the number of times it has called the function "twice" (the idea is that I only want the function "twice" to execute "twice", no matter how often it is called via "runTwice" '). Could you help me?

The functions are listed below:

var count = 1;
    
function twice(num){
  return num*2;
}

function runTwice(func){
  if (count<3){
    count++;
    return func;
  } else {
    return 'Function cannot run!';
  }
}
    
var myFunc = runTwice(twice)
    
var output = [];

for (var i = 0; i < 3; i++){
  output.push(myFunc(i));
}

console.log(output);
      

Run codeHide result


I would like the output to be [0, 2, "Function cannot work!" ].

I can make this work if I count the function "twice", but I want to understand why it doesn't work as shown above.

+3


source to share


2 answers


The function runTwice

should return another function that decides whether the function should be called func

(using ) or to return a string message: Function.prototype.apply

function twice(num){
    return num * 2;
}

function runTwice(func){
    var count = 0;                              // this will be trapped in a closure along with func
    return function() {                         // this is the function that gets called
      count++;                                  // it increments its version of the count variable
      if(count <= 2)                            // if count is less than 2
        return func.apply(this, arguments);     // then it calls the function func with whatever arguments passed into it and return the returned value of that call
      return "Not available anymore!";          // otherwise (count > 2), then it returns a string
    }
}

var myFunc = runTwice(twice);

for (var i = 0; i < 3; i++){
    console.log(myFunc(i));
}
      

Run codeHide result


Better:



You can also specify the number of times allowed:

function double(num) {
    return num * 2;
}

function triple(num) {
    return num * 3;
}

function run(func, times){
    var count = 0;                              // this will be trapped in a closure along with func and times
    return function() {                         // this is the function that gets called
      count++;                                  // it increments its version of the count variable
      if(count <= times)                        // if count is less than times
        return func.apply(this, arguments);     // then it calls the function func with whatever arguments passed into it and return the returned value of that call
      return "Not available anymore!";          // otherwise (count > times), then it returns a string
    }
}

var double2times = run(double, 2);              // double2times can only be called 2 times
var triple5times = run(triple, 5);              // triple5times can only be called 5 times

for (var i = 0; i < 10; i++){
    console.log("Double:", double2times(i));
    console.log("Triple:", triple5times(i));
}
      

Run codeHide result


+1


source


Just for fun, I'll create a generic function expireAfter(invocable[, times[, message]])

:



function expireAfter(invocable, times = 2, message = 'Function cannot run!') {
  return function expires() {
    if (times > 0) {
      times--;

      return invocable.apply(this, arguments);
    }
    
    return message;
  }
}

function twice(n) {
  return n * 2;
}

var myFunc = expireAfter(twice);

console.log(Array(3)
  .fill()
  .map((_, index) => myFunc(index))
);
      

Run codeHide result


+1


source







All Articles