Разрешить запуск функции только n раз с функцией-оберткой - PullRequest
0 голосов
/ 23 февраля 2019

Мне нужно создать функцию-обертку для вызова функции multiply с заданным числом num раз, чтобы позволить multiply выполнить.nTimes(num,2) Затем присваивать runTwice - runTwice может быть любая функция, которая вызывает функцию 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 голосов
/ 23 февраля 2019

Видя, как Нина и Джето ответили на ваш вопрос, вот простой и похожий способ сделать это, который также ведет историю всех результатов на случай, если вы захотите получить их позже.

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
0 голосов
/ 23 февраля 2019

Ответ Нины великолепен.Вот альтернатива с кодом, который может выглядеть немного легче для чтения:

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
0 голосов
/ 23 февраля 2019

Вы можете использовать замыкание по числу и последнему значению, а также проверять счет и уменьшение и сохранять последний результат.

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