00:49
<James M Snell>

Wanted to get some opinions on some far-too-common promise patterns to see if folks might consider them worth addressing. Both minor but exceedingly common.

  1. The evil terrible empty catch handler... promise.catch(() => {}) ... done to suppress unhandled rejections when we don't actually care about rejections on those promises. Several web standard specs specifically indicate that rejections on certain promises should be marked as handled and V8 and other engines have native ways of marking these, but in JS all we have is adding the catch handler... which ends up creating another promise...

  2. The never resolving promise... await new Promise(() => {})

For both, it might be nice to provide some syntactic sugar...

promise.markAsHandled();  // works on the current promise, no new promise created

await Promise.never();  // or maybe even Promise.never as a singleton that never settles

Both quite simple but useful

01:53
<bakkot>
Seems a shame engines can't just optimize the specific .catch pattern but yeah something like that seems useful
01:54
<bakkot>
much less sure about the never-resolving promise thing, that has never come up in my experience though mine is not necessary representative
02:32
<arai>
I use the never resolving promise pattern quite often while debugging automated test cases, in order to pause the execution and investigate the state. for this case, it might make more sense to provide the feature in the test harness tho
03:00
<James M Snell>
Yeah, comes up nearly exclusively in tests (the never resolving promise). That one probably isn't worth doing anything with because of that...
03:00
<James M Snell>
but the empty catch(() => {}) comes up WAY too often
05:33
<ljharb>
i mean, unhandled rejections are a normal part of the language, and it really sucks that both the web and node turn that into a failure mode
05:33
<ljharb>
imo that's the reason it comes up, because implementations introduced an artificial/unnecessary failure mode
06:25
<eemeli>
Why not allow for an argument-less .catch() instead of adding a new method?
06:48
<Ashley Claymore>
Because that would still create a new promise 
06:54
<Zb Tenerowicz (ZTZ/naugtur)>
Not if argument-less catch returned void. But it feels like a footgun
06:58
<Ashley Claymore>
Yeah I don't think we'd want to overload the return type like that 
13:10
<James M Snell>
Yeah, a polymorphic return would make me even more sad than an empty catch handler
18:45
<Zb Tenerowicz (ZTZ/naugtur)>
I like the Promise.never singleton promise.ignore() would be my naming choice instead of markAsHandled
18:54
<bakkot>
Ignore kind of implies no handlers will be invoked, to me
18:56
<James M Snell>
A nice quality of Promise.never is that the impl can be optimized to not retain any reactions. Promise.never.then(fn) can be a no-op that does not retain fn at all.
19:30
<rbuckton>
I am reminded that some promise implementations that predated native promises had a .done(onfulfilled, onrejected) method that had no return value.
19:45
<bakkot>
from what I can tell spidermonkey at least is capable of not allocating a result when it is syntactically known not to be used, e.g. https://searchfox.org/firefox-main/source/js/src/builtin/Array.cpp#3440-3442
19:46
<bakkot>
I don't know if it does this for .then/.catch but I don't see any reason why it couldn't
19:46
<bakkot>
though I guess the unhandled rejection handler makes that tricky, hm
19:48
<bakkot>
actually it looks like they do: https://searchfox.org/firefox-main/rev/0271096efe3ea9e8c9a5479f26774f1842ef0585/js/src/builtin/Promise.cpp#7358
19:49
<bakkot>
oh and they just materialize a promise on the fly for the unhandled rejection handler if it was optimized out, very nice https://searchfox.org/firefox-main/rev/0271096efe3ea9e8c9a5479f26774f1842ef0585/js/src/builtin/Promise.cpp#4100-4107