Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 };
like image 893
Ming Huang Avatar asked Feb 23 '19 16:02

Ming Huang


People also ask

What is a wrapper function in JavaScript?

In programming languages such as JavaScript, a wrapper is a function that is intended to call one or more other functions, sometimes purely for convenience, and sometimes adapting them to do a slightly different task in the process. For example, SDK Libraries for AWS are examples of wrappers.

What is wrapper function C++?

A wrapper function is a subroutine (another word for a function) in a software library or a computer program whose main purpose is to call a second subroutine or a system call with little or no additional computation.

How do you run a function continuously?

In order to run a function multiple times after a fixed amount of time, we are using few functions. setInterval() Method: This method calls a function at specified intervals(in ms). This method will call continuously the function until clearInterval() is run, or the window is closed.

When to wrap a function?

You may want to wrap a function to add instrumentation or temporary debugging logic. You can also change the behavior of an external library without needing to modify the source.


3 Answers

You could use a closure over the count and the last value and check count and decrement and store the last result.

const
    multiply = (a, b) => a * b,
    maxCall = (fn, max, last) => (...args) => max && max-- ? last = fn(...args) : last,
    mult3times = maxCall(multiply, 3);

console.log(mult3times(2, 3));
console.log(mult3times(3, 4));
console.log(mult3times(4, 5));
console.log(mult3times(5, 6));
console.log(mult3times(6, 7));
like image 124
Nina Scholz Avatar answered Oct 23 '22 18:10

Nina Scholz


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
like image 2
Jeto Avatar answered Oct 23 '22 16:10

Jeto


Seeing how both Nina and Jeto have answered your question, here is a simple and similar way to do it that also keeps a history of all the results in case you want to get them at a later time.

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

function runMaxNTimes(num, callBack) {
  var results = new Array(num);
  var callTimes = 0;
  return function(...params) {
    return results.length > callTimes ?
      results[callTimes++] = callBack(...params) :
      results[callTimes - 1];
  };
}

var runTwice = runMaxNTimes(2, 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
like image 1
nick zoum Avatar answered Oct 23 '22 18:10

nick zoum