Problem : Allow One Function Call | #2666 | LeetCode
Given a function `fn`, return a new function that is identical to the original function except that it ensures `fn` is called at most once.
The first time the returned function is called, it should return the same result as `fn`.
Every subsequent time it is called, it should return `undefined`.
Input: fn = (a,b,c) => (a + b + c), calls = [[1,2,3],[2,3,6]]
Output: [{"calls":1,"value":6}]
Explanation:
const onceFn = once(fn);
onceFn(1, 2, 3); // 6
onceFn(2, 3, 6); // undefined, fn was not called
Input: fn = (a,b,c) => (a * b * c), calls = [[5,7,4],[2,3,6],[4,6,8]]
Output: [{"calls":1,"value":140}]
Explanation:
const onceFn = once(fn);
onceFn(5, 7, 4); // 140
onceFn(2, 3, 6); // undefined, fn was not called
onceFn(4, 6, 8); // undefined, fn was not called
/**
* @param {Function} fn
* @return {Function}
*/
var once = function (fn) {
let hasBeenCalled = false; // Initialize a flag to track whether fn has been called
return function (...args) {
if (!hasBeenCalled) {
// If fn has not been called before
hasBeenCalled = true; // Set the flag to true to indicate that fn has been called
return fn(...args); // Call fn with the provided arguments and return its result
} else {
// If fn has already been called
return undefined; // Return undefined as specified
}
};
};
/**
* let fn = (a,b,c) => (a + b + c)
* let onceFn = once(fn)
*
* onceFn(1,2,3); // 6
* onceFn(2,3,6); // returns undefined without calling fn
*/
Let's break down the code step by step:
1. The code defines a function called `once` that takes a single parameter, `fn`, which is expected to be a function.
2. Inside the `once` function, a boolean variable named `hasBeenCalled` is initialized to `false`. This variable will be used to track whether the `fn` function has been called previously.
3. The `once` function returns a new function created using a closure. This new function accepts any number of arguments using the rest operator `...args`.
4. Inside the returned function:
- It checks if `hasBeenCalled` is `false`, which means that the `fn` function has not been called before.
- If `hasBeenCalled` is `false`, it sets `hasBeenCalled` to `true` to indicate that the `fn` function has now been called.
- It then calls the original `fn` function with the provided arguments `...args` and returns its result.
5. If `hasBeenCalled` is `true`, indicating that the `fn` function has already been called previously, the returned function simply returns `undefined`, adhering to the behavior of allowing `fn` to be called at most once.
6. Below the `once` function, there's an example of how to use it:
- It defines a function `fn` that takes three arguments and returns their sum.
- It creates a new function `onceFn` by calling `once(fn)`. This new function, `onceFn`, is now capable of ensuring that `fn` is called at most once.
7. It demonstrates the usage of `onceFn`:
- The first call to `onceFn(1, 2, 3)` returns `6` because it calls the original `fn` function and calculates the sum of the arguments.
- The second call to `onceFn(2, 3, 6)` returns `undefined` without calling the original `fn` function again, as it has already been called once.
In summary, the `once` function creates a wrapper function that ensures the original function `fn` is called only once. Subsequent calls to the wrapper function return `undefined` to prevent additional calls to `fn`. This is achieved by using a flag (`hasBeenCalled`) to keep track of whether `fn` has been called before.