Live data from Hacker News

How do Promises Work?

robotlolita.me

61–70 of 91 posts

Re: How do Promises Work?

#61

Earlier quoted context omitted.

What are you going to do in Javascript, though, if the I/O takes some time to happen? In golang or lua or whatever I can say "this execution context should block on the I/O for x seconds, then give up and return an error." (the other tens of thousands of execution contexts can keep going) In Javascript I would probably do... the same thing? But I would do it using promises?

You can do something like this (using Bluebird's Promise.delay for convenience): // using Promise.race so whoever finishes first wins var fetchingWithTimeout = Promise.race([ // first promise: actually try to perform the computation fetching, // second promise: wait x seconds, then reject Promise.delay(x*1000).then(Promise.reject('Timed out')), ]); You can apply the timeout wherever you want (or apply different timeo…

Yeah, that would work. My question is really whether I should prefer this over a sequential API that does the same thing, and why. "Does the same thing" here includes the property of "not blocking an OS-level thread".

Re: How do Promises Work?

#63
post #20
post #11

I have seen how Promises' concept was abused in a project at work. All the promises were just returning Future objects, and they were exposed everywhere. And, in case a future fails for some reason, there was no way to have a new Future: all users were doing future.get, resulting in an exception thrown to the caller. What a mess.

What is the difference between "Promise" and "Future"? From what I read, it is basically the same thing.

In Javascript: Promise is read-only (public interface), Deferred is writable (private)

on JVM: Future is read-only (public), Promise is writable (private)

The writable interface has "resolve" and "reject" to return a value. The readable interface has "then", "error", "finally" etc which let you compose and combine functions that deal in asynchronous values.

The best Javascript implementation of promises is Bluebird, which doesn't expose a Deferred instance to avoid confusion, it is very nice. bluebirdjs.com/docs/api-reference.html

Re: How do Promises Work?

#64
post #42
post #24

> Another way of solving this problem comes from the realisation that we only really need to keep track of the dependencies for a promise while the promise is in the pending state, because once a promise is fulfilled we can just execute the function right away! This is a common gotcha in Javascript implementations, in that you think you want this, but you really don't! Now you never know if your code is synchronous o…

I think you're maybe referring to a broken `Promise` implementation. Here's a good article about how callbacks get scheduled: https://jakearchibald.com/2015/tasks-microtasks-queues-and-s...

Oh yeah, I don't think any real/production Promise implementation behaves this way - but it can be unclear why. As a beginner, you might expect Promise.resolve('foo').then(...) to happen immediately, as the quoted passage suggests; I was trying to get at why that's not the case.

Re: How do Promises Work?

#65
post #43

Earlier quoted context omitted.

This is a common gotcha in Javascript implementations, in that you think you want this, but you really don't! No, I really, really, DO want this. And I want my entire codebase written in such a way that this is fine. You need consistent abstractions to make asynchronous logic flow comprehensible. And once you have them, stick to them rigorously. Promises are such an abstraction. Build on it, don't ruin it. Yes, there…

I think you (or I) misunderstand what you're replying to. When they said "you really don't want this", they're saying you don't want promises to sometimes be async and sometimes resolve in the same tick. Always make them async. That agrees with you, since it would mean you can always treat promises the same.

>sometimes be async and sometimes resolve in the same tick

That's still asynchronous though isn't it? (Correct me if I'm wrong I'm just spitballing, still learning).

There's no lower bound on the minimum amount of ticks a process can take for it to be async. What gives it that async-ness is that the upper bound is unknown, indeterminate, and changeable.

Ergo, if some process is sometimes synchronous, and sometimes asynchronous, it's really a process that is asynchronous, but just so happens to occasionally execute in synchronous-like time.

Re: How do Promises Work?

#66
post #44

See section about handling error and promises. Very well done! You won't see that in the typical "check out how cool promises are, async and fast all the things". And promises indeed look cool, and make for nice short demos and they are easy to understand in short examples. Only when you start building a large applications based on them, where error handling has to be done, you start realizing they are bit like threa…

IMO the Promise API in javascript is incomplete when it comes to error handling. If you use the native implementation, all you have for error handling is .catch, but that changes the result of the computation. It would be extremely convenient to have out of band onSuccess/Failure/Complete lifecycle callbacks which don't have return values, but do let you perform logging, etc. on the side without affecting the result. You wind up having to catch errors and re-throw them, which is error-prone and janky.

Re: How do Promises Work?

#67
post #65

Earlier quoted context omitted.

I think you (or I) misunderstand what you're replying to. When they said "you really don't want this", they're saying you don't want promises to sometimes be async and sometimes resolve in the same tick. Always make them async. That agrees with you, since it would mean you can always treat promises the same.

>sometimes be async and sometimes resolve in the same tick That's still asynchronous though isn't it? (Correct me if I'm wrong I'm just spitballing, still learning). There's no lower bound on the minimum amount of ticks a process can take for it to be async. What gives it that async-ness is that the upper bound is unknown, indeterminate, and changeable. Ergo, if some process is sometimes synchronous, and sometimes as…

The meaning of 'tick' here is special, since we're talking about Node. It's not a measure of time, it's an iteration of Node's event loop. Because Node is single-threaded, everything that happens in a single tick (i.e, one run of the event loop) is in the same execution context/stack/call tree/whatever you want to call it. So we generally call this "synchronous", although technically you could be holding onto the tick forever, firing off a bunch of nonblocking IO in there and doing your own polling/event management.

Of course, that would be silly, since Node manages an event loop for you. So your nonblocking IO would instead push events onto the queue, and let Node move on to the next tick. If something happens in a different tick, it gets its own clean slate of an execution context, and we call this "async", since the function that triggered it is no longer running.

Re: How do Promises Work?

#68
post #37

Earlier quoted context omitted.

Some Promise library add support for things like `.timeout` so you can force a promise to reject if the promise takes too long to resolve. In cases like a node.js server, Promises allow a single node instance to handle thousands of concurrent requests because the event loop isn't blocking waiting for a single IO request to complete, the process can happily do lots of other things while Promises are pending.

Yes, I expect Promise libraries to support timeouts. So it's right that promises allow me to do the same thing I would do with sequential code in other languages? If I had the option of using coroutines when would I choose to use promises? Edit: I'm asking because the context of this thread is that one person said that sequential APIs for asynchronous operations, such as open(2), are pretty nice, and someone else sai…

If you have promises OR you have coroutines, your life is good. Either way, you don't have to choose between writing fragile sequential code and writing error-prone synchronization logic.

If you don't have either, then you'll probably end up re-implementing one or the other eventually anyway.

Re: How do Promises Work?

#69
post #43
post #24

> Another way of solving this problem comes from the realisation that we only really need to keep track of the dependencies for a promise while the promise is in the pending state, because once a promise is fulfilled we can just execute the function right away! This is a common gotcha in Javascript implementations, in that you think you want this, but you really don't! Now you never know if your code is synchronous o…

This is a common gotcha in Javascript implementations, in that you think you want this, but you really don't! No, I really, really, DO want this. And I want my entire codebase written in such a way that this is fine. You need consistent abstractions to make asynchronous logic flow comprehensible. And once you have them, stick to them rigorously. Promises are such an abstraction. Build on it, don't ruin it. Yes, there…

I'm going to say that I've also been bitten by this, but in C#. Callbacks (or async tasks/promises, observables, etc.) should not be called immediately when they are registered. It makes it way too hard to figure out if your code is correct.

This doesn't break the abstraction, but it does make the abstraction simpler. It means that your callbacks (or whatever abstraction is built on top of them) are always called from the same context.

Re: How do Promises Work?

#70
post #67
post #65

Earlier quoted context omitted.

>sometimes be async and sometimes resolve in the same tick That's still asynchronous though isn't it? (Correct me if I'm wrong I'm just spitballing, still learning). There's no lower bound on the minimum amount of ticks a process can take for it to be async. What gives it that async-ness is that the upper bound is unknown, indeterminate, and changeable. Ergo, if some process is sometimes synchronous, and sometimes as…

The meaning of 'tick' here is special, since we're talking about Node. It's not a measure of time, it's an iteration of Node's event loop. Because Node is single-threaded, everything that happens in a single tick (i.e, one run of the event loop) is in the same execution context/stack/call tree/whatever you want to call it. So we generally call this "synchronous", although technically you could be holding onto the tic…

That makes a lit of sense, thanks for the explanation.
Post reply on HN