Search code examples
javascriptwrapperexecute

Only allowing a function to run n times with wrapper function


I need to make a wrapper function to invoke a function multiply with a given number num of times to allow the multiply to execute. nTimes(num,2) Then assign to runTwice -- runTwice can be any function that invoke the nTimes function which given a different num input--

In my case, for simplicity, I am only allowing it to run 2 times num=2 If we run the runTwice function the first time and the second time it will return the result of multiply function calculated with the inputs for multiply. Any invocation after the second time will not run the multiply function but will return the latest result of the multiply function.

Here is my implementation using an object to keep track of how many times we have execute the function, the max number allowed to execute and the latest result of multiply

 'use strict'
//use a counter object to keep track of counts, max number allowed to run and latest result rendered
let counter = {
    count:0,
    max: 0,
    lastResult: 0
};

let multiply = function(a,b){
    if(this.count<this.max){
        this.count++;
        this.lastResult = a*b;
        return a*b;
    }else{
        return this.lastResult;
    }
}

// bind the multiply function to the counter object
multiply = multiply.bind(counter);

let nTimes=function(num,fn){
    this.max = num;
    return fn;
};

// here the nTimes is only executed ONE time, we will also bind it with the counter object
let runTwice = nTimes.call(counter,3,multiply);

console.log(runTwice(1,3)); // 3
console.log(runTwice(2,3)); // 6
console.log(runTwice(3,3)); // 6
console.log(runTwice(4,3)); // 6

Note that I have altered the simple multiply quite a bit and bind it the counterobject to make it work. Also using call on nTimes to bind counter object.

What can I do to implement the same result with a wrapper function but less alteration to the simple multiply function?

Let's say the multiply function is very simple:

let multiply = function(a,b){ return a*b };

Solution

  • Nina's answer is great. Here's an alternative, with code that might look slightly easier to read:

    function multiply(a, b) {
      return a * b;
    }
    
    function executeMaxTimes(max, fn) {
      let counter = 0, lastResult;
      return (...args) => counter++ < max 
        ? lastResult = fn(...args) 
        : lastResult;
    }
    
    const multiplyMaxTwice = executeMaxTimes(2, multiply);
    
    console.log(multiplyMaxTwice(1, 3)); // 3
    console.log(multiplyMaxTwice(2, 3)); // 6
    console.log(multiplyMaxTwice(3, 3)); // 6
    console.log(multiplyMaxTwice(4, 3)); // 6