alexbuki
@alexbuki
программист js

Как возвращать первый вызов функции?

Реализовать once – функцию, которая принимает другую функцию, в качестве аргумента, и возвращает новую версию этой функции. Новая версия должна возвращать то же, что и оригинальная функция, но все последующие вызовы должны возвращать результат самого первого вызова. Пример:
let inc = a => a + 1;
    let incOnce = once(inc);
     let res1 = incOnce(42); //res1 is 43
    let res2 = incOnce(77); //res2 is 43, NOT 78


Требования: 1. Не допустимы повторные вызовы функции-аргумента 2. Функция once должна корректно работать с функциями нескольких аргументов 3. Функция once должна корректно работать с методами 4. Функция once должна корректно работать с функциями, которые кидают исключения. В таких случаях, новая функция должна выбрасывать одно и то же исключение при всех последующих вызовах.

Написал пробный код, но счетчик не работает:
let counter = 0;
    let firstCall;
    let once = ()=>{
    
        if (counter>1){
            return firstCall
        }
            counter ++
        firstCall = inc;
            return inc
    
    };
    let inc =a=>a+1;
    
    let incOnce = once(inc);
    
    let res1 = incOnce(42);
    let res2 = incOnce(77);
    console.log(res1, res2); // выводит 43 и 78
  • Вопрос задан
  • 146 просмотров
Решения вопроса 2
@StockholmSyndrome
let once = (func) => {
  let counter = 0; 
  let result;
  let error;

  return function(...args) {
    if (error) {
      throw error;
    }
    if (counter > 0) {
      return result;  
    }

    try {
      counter++;
      return result = func(...args); 
    } catch (e) {
      throw error = e;
    }
  }
}


let incOnce = once((a) => a + 1); 
incOnce(42); // 43
incOnce(77); // 43

let errOnce = once((a) => {
  if (a == 1) {
    throw new Error('a');
  }
});
errOnce(1); // Error
errOnce(2); // Error
Ответ написан
Комментировать
Как-то так:
function doOnce (fn) {
  let value;
  let error;
  let cached = false;
  return function () {
    if (cached) {
      if (error) throw error;
      return value;
    }
    cached = true;
    try {
      value = fn.apply(this, arguments);
      return value;
    } catch (e) {
      error = e;
      throw e;
    }
  };
}

const inc = a => a+1;
const incOnce = doOnce(inc);

const fail = error => { throw error };
const failOnce = doOnce(fail);

console.log(
  incOnce(1), // 2
  incOnce(3), // 2
  incOnce(5), // 2
);

try {
  failOnce(new TypeError());
} catch (e) {
  console.log(e); // TypeError
}

try {
  failOnce(new RangeError());
} catch (e) {
  console.log(e); // TypeError
}

try {
  failOnce(new ReferenceError());
} catch (e) {
  console.log(e); // TypeError
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы