Skip to content

Instantly share code, notes, and snippets.

@farhad-taran
Created May 14, 2021 18:50
Show Gist options
  • Save farhad-taran/aae0bf89b461761712a5c5cf51f5673b to your computer and use it in GitHub Desktop.
Save farhad-taran/aae0bf89b461761712a5c5cf51f5673b to your computer and use it in GitHub Desktop.
Creating the Lazy pattern construct in javascript

when fetching an expensive and costly object that might not be used frequently or not at all, its best to load and fetch it lazily, ie, only fetch it when the process requires it.

the below code is an implementation of the Lazy pattern which is already available in C#.

export default class Lazy {
  #value;
  #fetch;

  constructor(valueFetcher) {
    this.#fetch = valueFetcher;
  }

  value = () => this.#value || (this.#value = this.#fetch());
}

Tests:

import Lazy from '../lazy';

describe('Lazy', () => {
  it('only fetches value when asked for it', () => {
    let wasFetched = false;
    const item = new Lazy(() => {
      wasFetched = true;
      return 1;
    });

    expect(wasFetched).toBe(false);
    expect(item.value()).toBe(1);
  });

  it('returns value when asked for', () => {
    let wasFetched = false;
    const item = new Lazy(() => {
      wasFetched = true;
      return 1;
    });

    expect(item.value()).toBe(1);
    expect(wasFetched).toBe(true);
  });

  it('returns saved value when asked for it multiple times', () => {
    let fetchCount = 0;
    const item = new Lazy(() => {
      fetchCount++;
      return 1;
    });

    expect(item.value()).toBe(1);
    expect(item.value()).toBe(1);
    expect(fetchCount).toBe(1);
  });

  it('updates saved value when asked to do so', () => {
    const item = new Lazy(() => ({innerValue : 1}));
    item.value().innerValue = 2;
    expect(item.value().innerValue).toBe(2);
  });
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment