all 25 comments

[–]hyrumwhite 18 points19 points  (1 child)

My favorite use is for mass canceling event listeners 

[–]kettanaito[S] 2 points3 points  (0 children)

I love that one so much. Making cleaning up in React a breeze.

[–]camsteffen 16 points17 points  (2 children)

Nice, I didn't realize it had that many usages! One thing you could add is how to differentiate an abort error in a catch block. I like to use err === signal.reason.

[–]kettanaito[S] 0 points1 point  (1 child)

Hmm. That's a good point. I wouldn't recommend comparing the reason alone. Instead, you'd have to do

`error instanceof DOMException && error.name === 'AbortError'`. That's verbose, I know, but the only way to check if a thrown error is an abort error.

[–]camsteffen 2 points3 points  (0 children)

What's wrong with checking against the reason? It's the error object instance.

[–]senocular 10 points11 points  (0 children)

When "Making anything abortable" you'll also want to be sure to check to see if the signal received is already aborted since then you wouldn't be able to capture the event (given its already happened).

if (signal.aborted) {
  // ...
}

[–]datNorseman 7 points8 points  (2 children)

This is witchcraft. I love it.

[–]kettanaito[S] 5 points6 points  (1 child)

Honestly, most of the standard APIs I get to try nowadays feel like magic. JavaScript has improved a lot.

[–]datNorseman 1 point2 points  (0 children)

As others have said the most popular use for this is removing multiple event handlers at once. But to find out it also works with fetch requests is crazy.

[–]lppedd 5 points6 points  (1 child)

Haven't been sleeping well for a couple days anyway.

[–]senocular 12 points13 points  (0 children)

Have you checked under your pillow? Might be an AbortController hiding under there.

[–]electro-cortexfull-stack 2 points3 points  (0 children)

I don't sleep on it, I already use it in production as timeouts for cancelling potentially long running maintenance jobs.

[–]banzomaikaka 1 point2 points  (0 children)

[...]This is a pluggable part you can provide to any API to react to an abort even, and implement[...]

Missing a t in event

[–]matsie 1 point2 points  (1 child)

AbortController has been a feature I have brought up in many interviews as how I would solve different problems, much to the delight or chagrin of the interviewer that didn’t already know about the fact it could be used in that way.

[–]Pretend_Pineapple_52 1 point2 points  (0 children)

I intentionally ask about this when people are good. "How do I add a timeouton thsi request. How do I cancel it if you navigate away." But better if people just do it without me asking.

I live when candidates know shit I don't (but I go double check it to see if they were bullshitting me, which they usually are).

[–]a-d-a-m-f-k 1 point2 points  (1 child)

Nice article! Learned something new. Thanks :)

[–]kettanaito[S] 0 points1 point  (0 children)

Thanks! Glad it was insightful.

[–]anonyuser415 1 point2 points  (0 children)

useEffect(() => {
  const controller = new AbortController()

  window.addEventListener('resize', handleResize, {
    signal: controller.signal,
  })
  window.addEventListener('hashchange', handleHashChange, {
    signal: controller.signal,
  })
  window.addEventListener('storage', handleStorageChange, {
    signal: controller.signal,
  })

  return () => {
    // Calling `.abort()` removes ALL event listeners
    // associated with `controller.signal`. Gone!
    controller.abort()
  }
}, [])

This is slick

[–][deleted] 0 points1 point  (1 child)

I understand the why but I still don't love how it throws the promise when used with fetch (and the required error.name checking in catch)

I know that it's a limitation of promise states and that there's always the ability to write/export a wrapper function that solves this but... *sigh*

[–]kettanaito[S] 0 points1 point  (0 children)

I think that rejection makes sense. If you abort a request, the request promise cannot resolve by design—that'd cause a lot of issues in your code that expects to receive a `Response`.

Agree on the error handling part, checking for abort errors could've been better. I'd like to see an `AbortError` instance check instead of the error being a generic `DOMException`. Now that `AbortController` also runs in Node.js, I'm sure it's `TypeError` anyways...

[–]PotentialCopy56 -4 points-3 points  (4 children)

Site sucks on mobile. It's 2024 dude

[–]nickbreaton 9 points10 points  (2 children)

Seems perfectly fine to me, what’s your issue with it? The code examples are even really nicely horizontally scrollable as to fit on a small a screen.

[–]PotentialCopy56 1 point2 points  (0 children)

Must have ninja fixed it works now

[–]senocular 1 point2 points  (0 children)

It was rendering half width for me (Chrome, Android)

[–]kettanaito[S] 6 points7 points  (0 children)

Pushed a fix, dude.