1

I am aware that, as of 2022 Q2, JavaScript does not have destructors.
EDIT: the Accepted answer to that question is incorrect due to being out-of-date. See my answer, h/t UnholySheep, for an update from 2020.

However, it looks like my workaround in the following function to leverage closures' GC may have some compatibility impact.

function to_async(f) {
    let src = f.toString();
    let src_worker = [ // TODO: pass exceptions, too
        "self.addEventListener('message', async e => { let arguments = e.data.arguments; let result = await (\n",
        src,
        "\n)(...arguments); self.postMessage({result: result}, [result].filter(x => typeof x === 'object')); }, {once: true});"
    ];

    // MEMORY LEAK; ENABLE AT YOUR OWN RISK!!
    //let src_worker_url = URL.createObjectURL(new Blob(src_worker, {type: 'application/javascript'}));

    // Workaround / alternative implementation in case function is called non-finite number of times
    let src_worker_url = 'data:application/javascript,' + encodeURIComponent(src_worker.join(""));

    async function g() {
        let w = new Worker(src_worker_url);
        let p = new Promise(res => w.addEventListener('message', e => res(e.data.result), {once: true}));
        w.postMessage({arguments: Array.from(arguments)}, Array.from(arguments).filter(x => typeof x === 'object'));
        let result = await p;
        return result;
    }
    return g;
}

I would like to set g[Symbol.destructor] = () => URL.revokeObjectURL(src_worker_url); before returning it.

Is there any way I can achieve something like this in ES6? Or is my current workaround with let-inside-a-closure of a data: URI the best it gets for this use-case?

  • 1
    What about using [`FinalizationRegistry`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry)? Isn't that what you are looking for? – UnholySheep Jun 24 '22 at 22:08
  • @UnholySheep That appears to be _exactly_ what I'm looking for! I scrolled through all the answers with double-digit upvotes on q29333017 and didn't see it... – JamesTheAwesomeDude Jun 24 '22 at 22:11
  • 1
    To be fair `FinalizationRegistry` is a very new feature (ES2021) and the linked question is from 2015 – UnholySheep Jun 24 '22 at 22:14

0 Answers0