0

I want to cache performance intensive object generation using the Multiton pattern in JavaScript with an asynchronous function. I provide an example and would like to know if I implemented that correctly, i.e. whether that is enough to guarantee that an object with the same name will never be generated twice, no matter the asynchronous order of execution.

const things = new Map();

// in real life, fetch from network or other asynchronous, slow operation
async function slowFunc() {
    return Math.floor(Math.random() * Math.floor(100));
}

class Thing {
    constructor(n) {
        this.n = n;
    }

    static async get(name) {
        let thing = things.get(name);
        if (thing) {
            console.log("Reusing existing", name, "with n=", (await thing).n);
            return thing;
        }
        const promise = slowFunc().then(n => {
            thing = new Thing(n);
            console.log("Creating new", name, "with n=", n);
            return thing;
        }, );
        things.set(name, promise);
        return promise;
    }
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
</head>
<body>
  <button onclick="Thing.get('a');">Make an A</button>
  <button onclick="Thing.get('b');">Make a B</button>
</body>
</html>
Konrad Höffner
  • 11,100
  • 16
  • 60
  • 118
  • 1
    seems right. only strange thing is that you have "the creator fn/factory method" as a static function on the very class you want to keep unique instances of – japrescott Feb 10 '20 at 15:12
  • @japrescott: I did it like this in Java, what is the usual location to put the factory method in JavaScript? – Konrad Höffner Feb 10 '20 at 15:54
  • its not wrong, its just a bit strange :) I normally have a separate Factory class/method which is the only exported method (the class isn't exported thus preventing accidental misusage). – japrescott Feb 10 '20 at 16:00
  • @japrescott: That makes total sense as JavaScript doesn't have private constructors, thanks! – Konrad Höffner Feb 10 '20 at 16:19

0 Answers0