Live data from Hacker News

How do Promises Work?

robotlolita.me

41–50 of 91 posts

Re: How do Promises Work?

#41
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.

People do not use the terms consistently.

The difference is SUPPOSED to be that a Future is read-only while a Promise is settable. And should be set at most once! So you can use a Promise as a Future, but you can't always use a Future as a Promise.

Linguistically you can understand this as, "I Promise you'll see a Future answer." I need to be able to write to the Promise to fulfill it. You can only hope that some day the Future will arrive.

Re: How do Promises Work?

#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...

Re: How do Promises Work?

#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 are lots of ways to ruin it. And for every way it can be ruined, there is a way to make it work without breaking the abstraction. Do the latter.

Re: How do Promises Work?

#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 threads. Promise callback chains started from one event, can interfere with other promise callback chains that started from another event. And if they modify the same data, you now also have a race condition as well.

I would basically look at this statement "In the synchronous world, it’s very simple to understand computations when thinking about functions: you put things into a function, and the function gives you something in return" and follow through, but in a different direction -- pick the synchronous world if you can.

Sequential things should be sequential and concurrent things should be concurrent. Single request processing is sequential. For this request do x,y,z in order. Can't do y unless x finished. Well sit and wait for x to finish. But requests themselves can be concurrent and run in parallel. For example a request comes in, reads the database, updates the database, bumps metrics, makess other sub-requests and then responds. It is sequential and should be kept sequential. If you platform cannot handle that, think very well about your platform, and perhaps pick a better platform. What does that mean practically? It means picking green threads (Python gevent, eventlet), it means Elixir, Erlang, Go goroutines, Rust's threads. Streams can be used as a higher level abstraction sometimes and so on.

Re: How do Promises Work?

#45

Earlier quoted context omitted.

I am not calling to ignoring the async nature of computing in general, I am calling for better tooling. The Linux (and other OS'es) kernel handles I/O asynchronously, yet processes using open(2) + friends work quite well and are usually written in synchronous style. That the actual asyncness is hidden in kernel space does in general not lead to bad programs; and whoever needs async in the space of a single process ca…

Imho in this area there is really no general good solution: Either you use the leaky blocking IO abstraction over the async IO - and you will require multiple threads/tasks for doing anything more complicated and lots of complex synchronization. Or you use the async APIs directly and need to work with callbacks/promises/etc., but you can at least avoid synchronization. I personally prefer the async solution, and I th…

> Either you use the leaky blocking IO abstraction over the async IO

What do you mean the leaky blocking IO. It is the non-blocking IO that is leaky, isn't it. If at the business logic there is a request being processed that needs to go through steps a,b,c and then return. b, can't be done unless a finishes and c unless b finishes is mapped pretty cleanly to an execution context of a thread/actor/goroutine/task/process.

Shoving IO callback functions in between handling the steps, or spreading them across callbacks or using promises is leaking the abstraction of the platform not being able to handle concurrent processing very well.

Re: How do Promises Work?

#46
post #9

Earlier quoted context omitted.

i love elixir actors / golang goroutines, since i don't have to give any special treatment to async operations.

Does elixir solve this problem? http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...

Good news! It does.

The platform is better designed and smart where you don't need red and blue function. You just have green functions (being a bit silly here with colors).

> [From Post] Async functions don’t compose in expressions because of the callbacks, have different error-handling, and can’t be used with try/catch or inside a lot of other control flow statements.

Good news again. Don't worry about that. Work sequentially as you need in inside each request/task. If you want to do multiple tasks in parallel, spawn multiple tasks. The Erlang folks (and Go-routine folks too but a bit in a different way) figured this out many years ago and have built large, complicated and reliable distributed systems (WhatsApp, smartphoneinternet gateways, databases etc...)

Re: How do Promises Work?

#47
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…

Promises also solve this problem. If you immediately resolve a promise it isn't actually resolved until the next event loop "tick": new Promise(resolve => resolve("resolved!")).then(result => console.log(result)); console.log("next statement"); Prints "next statement" then "resolved!".

You don't even have to resolve the promise via a callback for that to be the case - you can use the static resolve method. This is really useful if you have a function that can sometimes return a promise and sometimes a "normal" value.

    Promise.resolve("resolved!").then(result => console.log(result));
    console.log("next statement");

Re: How do Promises Work?

#48
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…

Rust no longer has green threads.

Another good way to make things sequential is C#-style async/await, which is enough syntactic sugar over promises that everything looks sequential again.

Re: How do Promises Work?

#49
post #37

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?

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 said no they're not pretty nice and we should explicitly deal with the asynchronous nature of operations like open(2) by NOT writing sequential code there.

Re: How do Promises Work?

#50
post #8

Nicely done, thanks! Still, having to explain a concept as simple as eventual computation reinforces my belief that promises as a whole is broken, and should be done in something that looks like synchronous code with some help of the underlying runtime. (And no, ES7's async is not good enough for me here)

NodeJS: you needed 5% of your code to be async, so we made everything async so you get to write awkward async-but-not-really code for the other 95%, too. That's better, right? At least that's how it's always felt when I've used it for anything non-trivial yet well within its typical set of use cases.

Compare this to Go, what % of go code do you think lies inside a go routine?
Post reply on HN