1

I need a function limitCalls (fn, maxCalls) that takes a function fn and returns a new function that can be called no more than the number of times specified in maxCalls. Test example:

 it('limitCalls', () => {
const makeIncrement = () => {
  let count = 0;

  return () => {
    count += 1;
    return count;
  };
};

const limitedIncrementA = limitCalls(makeIncrement(), 3);

expect(limitedIncrementA()).toBe(1);
expect(limitedIncrementA()).toBe(2);
expect(limitedIncrementA()).toBe(3);
expect(limitedIncrementA()).toBe(undefined);
expect(limitedIncrementA()).toBe(undefined);

const limitedIncrementB = limitCalls(makeIncrement(), 1);

expect(limitedIncrementB()).toBe(1);
expect(limitedIncrementB()).toBe(undefined);
expect(limitedIncrementB()).toBe(undefined);

});

I have:

var calls = 0;
export default function limitCalls(fn, maxCalls) {
  if (calls >= maxCalls) {
    return undefined;
  }
  calls += 1;
  return fn();
}

And error is limitedIncrementA is not a function. Help me please to realise it.

2 Answers 2

1

Instead of conditionally returning a function, always return a function that conditionally executes the fn callback:

function limitCalls(fn, maxCalls) {
  let count = 0;
  
  return function(...args) {
    return count++ < maxCalls ? fn(...args) : undefined;
  }
}

const limited = limitCalls(console.log, 3);

limited('one');
limited('two');
limited('three');
limited('four');

Sign up to request clarification or add additional context in comments.

Comments

0

In this snippet, limitedIncrementA isn't indeed a function. See this:

/* You're calling makeIncrement,
   so you're passing its return to 'limitCalls'
 */
const limitedIncrementA = limitCalls(makeIncrement(), 3);

/* Here, considering that makeIncrement exists,
   you're passing a reference to this functions,
   which can be called inside 'limitCalls'
 */
const limitedIncrementB = limitCalls(makeIncrement, 3);

So, supposing that makeIncrement returns 1, 2, 3, ..., your current code is equivalent to:

limitCalls(1, 3);

2 Comments

I got it. But according to the task I can't change test code. Is there any way to make limitedIncrementA a function inside limitCalls?
You can return what you called 'fn' then, without invoking (without parenthesis) but you can also check this code with a console.log(makeIncrement()) to see if this is actually returning a function

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.