Write once(fn). It returns a function that calls fn the first time it's called, with that call's this and arguments, and returns the result. Every later call returns the same first result without calling fn again, whatever arguments it gets.
The first result is remembered even when it's undefined, 0, or another falsy value. If fn calls the wrapper again while it's running, that inner call doesn't run fn a second time. Each call to once makes an independent wrapper.
const init = once((config) => {
console.log("connecting to", config.url);
return { connected: true };
});
init({ url: "a" }); // logs "connecting to a", returns { connected: true }
init({ url: "b" }); // returns the same object, logs nothing
const fn = spy(() => 42);
const init = once(fn);
expect(init()).toBe(42);
expect(fn).toHaveBeenCalledTimes(1);
const fn = spy();
const init = once(fn);
init();
init();
init();
expect(fn).toHaveBeenCalledTimes(1);
const double = once((x) => x * 2);
expect(double(5)).toBe(10);
expect(double(100)).toBe(10);
const make = once(() => ({}));
expect(make()).toBe(make());
const fn = spy();
once(fn)("a", 1);
expect(fn).toHaveBeenCalledWith("a", 1);
const obj = {
x: 7,
getX: once(function () {
return this.x;
}),
};
expect(obj.getX()).toBe(7);
const nothing = spy(() => undefined);
const init = once(nothing);
init();
init();
expect(nothing).toHaveBeenCalledTimes(1);
const zero = spy(() => 0);
const getZero = once(zero);
getZero();
expect(getZero()).toBe(0);
expect(zero).toHaveBeenCalledTimes(1);
let init;
const fn = spy(() => {
init();
return "done";
});
init = once(fn);
expect(init()).toBe("done");
expect(fn).toHaveBeenCalledTimes(1);
const fn = spy((x) => x);
const first = once(fn);
const second = once(fn);
expect(first(1)).toBe(1);
expect(second(2)).toBe(2);
expect(fn).toHaveBeenCalledTimes(2);
Run tests runs every test on your code, here in your browser. The problem is solved when they all pass.
Ctrl + Enter runs the tests (⌘ + Enter on a Mac).
I'm here to help with Once. I give hints, never the solution, so you get to solve it yourself. Ask for a hint, select code to ask about it, or press Ask Tuto why on a failing test.
Your first 3 answers need no account. for free to keep asking.