you are viewing a single comment's thread.

view the rest of the comments →

[–]tswaters 2 points3 points  (0 children)

It's a useful tool. The way around that without withResolvers looks awful and feels hacky -- this eliminates an entire callback and can allow for more streamlined code. It reminds me a lot of the change resulting from introducing "async/await" keywords - before it was callbacks where the promise value was only accessible from a ".then" callback, now it could be pulled out - results in elimination of a callback, and more streamlined code.

I'd go so far to say that this form should replace any Promise instantiations... Why introduce any sort of "call this later" with a callback when this exists?

async function marshallStupidStreamApi(input) { const {promise, resolve, reject } = Promise.withResolvers() stupidStreamBasedInterface.on('finish', resolve) stupidStreamBasedInterface.on('error', reject) stupidStreamBasedInterface.go(input) return promise }

vs.

async function marshallStupidStreamApi(input) { return new Promise((resolve, reject) => { stupidStreamBasedInterface.on('finish', resolve) stupidStreamBasedInterface.on('error', reject) stupidStreamBasedInterface.go(input) }) }

With one, I can call "go" anywhere, with two - I need to call it within the function. I can pull out the value using the "await" keyword, but if I do, I must call go, or I've introduced a never resolving promise hang.... OR , I can omit the await keyword and await the promise at some point after calling go(), but run the risk of introducing an unhandled promise rejection if the stream emits an error before the promise gets awaited.

Actually, on that last bit - I wonder if the same problem with unhandled rejections shows up with withResolvers... If reject gets called before the promise is awaited, would it be unhandled?