frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

Open in hackernews

A job queue in two lines of JavaScript

https://jameshfisher.com/2025/07/07/a-job-queue-in-two-lines-of-js/
47•chmaynard•3d ago

Comments

lerp-io•8h ago
The chain variable continuously grows because each call to enqueue() creates a new promise that references the previous one. This creates an ever-growing chain of promises that never gets garbage collected.
ath92•7h ago
Couldn’t the browser garbage collect the promises (and their callbacks) that have been rejected or resolved? I.e. effectively “shift” the promises at the start of the queue that have been dealt with and will never be relevant again?

At least this stackoverflow answer suggests the handlers are GC’ed: https://stackoverflow.com/questions/79448475/are-promise-han...

jameshart•7h ago
Why does the promise returned by a promise’s then() method need to reference that promise?

The original promise needs to reference the chained promise, not the other way round.

As jobs complete I would expect the top of the chain to be eligible to be garbage collected.

paulddraper•7h ago
Though it seems like that, no.

  a = b.then(c);
When `b` is resolved, it is garbage collected, even if a reference to `a` is retained.

(If the runtime maintains async stack traces, that could be an issue...but that is a common issue, and the stack depth is limited.)

bapak•6h ago
That's not how promises work, there's no chain. It's no different from

    await job1()
    await job2()
    await job3()
    await job4()
Except dynamic
ameliaquining•5h ago
At least in V8, this is not the case. To prove it, start a Chromium-based browser with the command-line flag --js-flags=--expose-gc, then go to https://runjs.app/play/#aWYgKCF3aW5kb3cuZ2MpIHsKICB0aHJvdyBu...
bigiain•2h ago
> This creates an ever-growing chain of promises that never gets garbage collected.

Modern frontend development performance best practise is to allow for garbage collection only when the browser crashes.

gabrielsroka•8h ago
That's TS, not JS.
90s_dev•7h ago
For now.

https://github.com/tc39/proposal-type-annotations

jameshart•7h ago
One line of TS, then two lines of JS (with a type annotation in one of them)
goloroden•5h ago
It’s not even 2 lines:

1. Type definition 2. Chain definition 3. Enqueue definition

jakelazaroff•5h ago
Line 1 is fully erased when transpiling, leaving two lines of JavaScript.
metadat•7h ago
I noticed the same thing when I saw the code. Is it honest for TFA to title it as "2-lines of Javascript" in this case?
dcre•5h ago
Oh, come on.
egorfine•43m ago
I came here to make the same comment.

I wonder why are you downvoted for being as factual and neutral as it is technically possible.

90s_dev•7h ago
I came across this trick a few months ago when I was dealing with what seemed to be a race condition from a chrome-only API, and I just felt so clever! I don't remember though whether the race condition actually was one or not though, and I eventually had to rip that entire class out of my codebase. But it's such a good feeling to know I came up with a solution that clever all by myself.
Inviz•7h ago
Chaining promises like this is not a good idea for high throughput cases (creates gc pressure), but perfectly valid for regular cases.
paulddraper•7h ago
Huh?

It creates 1 object allocation per enqueue.

Inviz•6m ago
yeah but it creates closure as well, which typically references some objects that isn't easy to GC. So if you have long-living promise with some data captured in closure, it will not be cleared. So doing then().then().then() may not release objects referenced in callbacks that resolved time ago.
vivzkestrel•6h ago
A production grade application would need a much more robust mechanism like BullMQ
theThree•6h ago
Something like this?

async function runTasks(tasks: Job[]) { for (let task of tasks) { try { await task() } catch (e) { } } }

foxygen•5h ago
This only works if you have the full list of tasks beforehand.
neals•5h ago
Anybody willing to walk me through this code? I don't get it.
foxygen•5h ago
chain is a global variable. It starts with an empty promise. First call to enqueue changes the (global)value of chain to emptyPromise.then(firstJob), second call to enqueue changes it to emptyPromise.then(firstJob).then(secondJob) and so on.
fwlr•5h ago
JavaScript promises are objects with a resolver function and an internal asynchronous computation. At some point in the future, the asynchronous computation will complete, and at that point the promise will call its resolver function with the return value of the computation.

`prom.then(fn)` creates a new promise. The new promise’s resolver function is the `fn` inside `then(fn)`, and the new promise’s asynchronous computation is the original promise’s resolver function.

cluckindan•4h ago
If you wanted to e.g. log something on failures, you’d need to do something like this:

    chain
      .then(job)
      .catch((err) => {
        console.error(err);
        return job();
      });
Otherwise failures would need to be logged by the job itself before rejecting the promise.
egorfine•44m ago
> If you need a job queue in JS

  type Job = () => Promise<unknown>;
This is not JS.

"AI discourse" is a joke

https://purplesyringa.moe/blog/ai-discourse-is-a-joke/
9•bertman•15m ago•1 comments

Show HN: Refine – A Local Alternative to Grammarly

https://refine.sh
151•runjuu•5h ago•64 comments

How I build software quickly

https://evanhahn.com/how-i-build-software-quickly/
78•kiyanwang•3h ago•33 comments

Let's Learn x86-64 Assembly (2020)

https://gpfault.net/posts/asm-tut-0.txt.html
278•90s_dev•12h ago•63 comments

Show HN: Ten years of running every day, visualized

https://nodaysoff.run
494•friggeri•3d ago•210 comments

Apple's Browser Engine Ban Persists, Even Under the DMA

https://open-web-advocacy.org/blog/apples-browser-engine-ban-persists-even-under-the-dma/
147•yashghelani•3h ago•66 comments

Emergent Misalignment: Narrow finetuning can produce broadly misaligned LLMs

https://arxiv.org/abs/2502.17424
119•martythemaniak•10h ago•33 comments

East Asian air cleanup likely contributed to acceleration in global warming

https://www.nature.com/articles/s43247-025-02527-3
25•defrost•1h ago•13 comments

A Century of Quantum Mechanics

https://home.cern/news/news/physics/century-quantum-mechanics
48•bookofjoe•3d ago•36 comments

How does a screen work?

https://www.makingsoftware.com/chapters/how-a-screen-works
438•chkhd•20h ago•90 comments

Bitcoin passes $120k milestone as US Congress readies for 'crypto week'

https://www.ft.com/content/1d4c5942-7190-45e1-9167-a5eacfd93982
20•sandbach•1h ago•18 comments

OpenCut: The open-source CapCut alternative

https://github.com/OpenCut-app/OpenCut
351•nateb2022•13h ago•111 comments

Binding Application in Idris

https://andrevidela.com/blog/2025/binding-application/
27•matt_d•3d ago•1 comments

The underground cathedral protecting Tokyo from floods (2018)

https://www.bbc.com/future/article/20181129-the-underground-cathedral-protecting-tokyo-from-floods
119•barry-cotter•4d ago•37 comments

APKLab: Android Reverse-Engineering Workbench for VS Code

https://github.com/APKLab/APKLab
117•nateb2022•13h ago•8 comments

A technical look at Iran's internet shutdowns

https://zola.ink/blog/posts/a-technical-look-at-irans-internet-shutdown
192•znano•17h ago•81 comments

Telefónica DE shifts VMware support to Spinnaker due to cost

https://www.theregister.com/2025/07/11/telefnica_germany_shifts_vmware_support/
20•rbanffy•1h ago•7 comments

Show HN: FFmpeg in plain English – LLM-assisted FFmpeg in the browser

https://vidmix.app/ffmpeg-in-plain-english/
100•bjano•3d ago•24 comments

Hypercapitalism and the AI talent wars

https://blog.johnluttig.com/p/hypercapitalism-and-the-ai-talent
97•walterbell•14h ago•66 comments

Show HN: ArchGW – An intelligent edge and service proxy for agents

https://github.com/katanemo/archgw/
88•honorable_coder•1d ago•8 comments

Show HN: Built a desktop app to organize photos locally with duplicate detection

https://organizer.flipfocus.nl/
16•mcvanhassel•4d ago•14 comments

Burning a Magnesium NeXT Cube (1993)

https://simson.net/ref/1993/cubefire.html
42•leoapagano•3d ago•15 comments

The Scourge of Arial (2001)

https://www.marksimonson.com/notebook/view/the-scourge-of-arial/
40•andsoitis•9h ago•24 comments

The upcoming GPT-3 moment for RL

https://www.mechanize.work/blog/the-upcoming-gpt-3-moment-for-rl/
207•jxmorris12•4d ago•87 comments

Myanmar’s proliferating scam centers

https://asia.nikkei.com/static/vdata/infographics/myanmar-scam-centers/
82•WaitWaitWha•6h ago•15 comments

GLP-1s are breaking life insurance

https://www.glp1digest.com/p/how-glp-1s-are-breaking-life-insurance
329•alexslobodnik•16h ago•395 comments

Show HN: A Raycast-compatible launcher for Linux

https://github.com/ByteAtATime/raycast-linux
169•ByteAtATime•17h ago•50 comments

C3 solved memory lifetimes with scopes

https://c3-lang.org/blog/forget-borrow-checkers-c3-solved-memory-lifetimes-with-scopes/
116•lerno•2d ago•95 comments

Concurrent Programming with Harmony

https://harmony.cs.cornell.edu/book/
4•todsacerdoti•3d ago•0 comments

James Webb, Hubble space telescopes face reduction in operations

https://www.astronomy.com/science/james-webb-hubble-space-telescopes-face-reduction-in-operations-over-funding-shortfalls/
100•geox•8h ago•60 comments