使用包装函数仅允许一个函数运行n次

时间:2019-02-23 16:21:06

标签: javascript wrapper execute

我需要制作一个包装函数,以调用给定次数multiply的函数num来执行multiplynTimes(num,2)然后分配给runTwicerunTwice可以是调用nTimes函数的任何函数,该函数会给出不同的num输入-

就我而言,为简单起见,我只允许它运行2次num=2 如果我们第一次运行runTwice函数,那么第二次它将返回multiply函数的结果,该结果是用multiply的输入来计算的。第二次之后的任何调用都不会运行multiply函数,但会返回multiply函数的最新结果。

这是我的实现,它使用一个对象来跟踪我们执行该函数的次数,允许执行的最大次数以及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

请注意,我已经对简单的multiply进行了相当大的改动,并将其绑定到counter对象以使其起作用。还使用对nTimes的调用来绑定counter对象。

我该怎么做才能通过包装函数实现相同的结果,而对简单的multiply函数的改动却更少?

让我们说multiply函数非常简单:

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

3 个答案:

答案 0 :(得分:3)

您可以对计数和最后一个值使用闭包,并检查计数和减量并存储最后的结果。

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));

答案 1 :(得分:2)

尼娜的答案很好。这是一种替代方法,其代码可能看起来更易于阅读:

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

答案 2 :(得分:1)

看看Nina和Jeto都如何回答您的问题,这是一种简单且类似的处理方式,它还保留了所有结果的历史记录,以备日后索取。

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