
How do Promises Work? - themichaellai
http://robotlolita.me/2015/11/15/how-do-promises-work.html
======
wonnage
> 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 or will run in a subsequent tick. Your call tree will look
completely different depending on race conditions...

This comes up in user code as well; any time you write a function that takes a
callback, it's probably a good idea to either always run it either in the same
call tree or in a new stack, but never mix the two. It's usually easier to
just do the latter using process.nextTick.

~~~
tlrobinson
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!".

~~~
jallardice
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");

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

~~~
runn1ng
What is the difference between "Promise" and "Future"?

From what I read, it is basically the same thing.

~~~
btilly
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.

~~~
inglor
That changes by language - what you say is true in Scala, but in JavaScript
the terminology is different. A future is not defined, a promise is a future
and a deferred is a promise.

~~~
btilly
That is what I mean about people being inconsistent.

The ideas are much older than Scala, JavaScript, and many of the people
commenting in this discussion. Believe it or not, both terms date back to the
late 1970s.

Scala got it right. JavaScript got it wrong. And polyglots like me have to
suffer with having to sort out who means what, where, on what platform.

------
radiospiel
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)

~~~
ashark
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.

~~~
dboreham
Despite the downvotes, you are absolutely correct. My feeling, after working
on a moderately complex server application in Node is that it was designed for
only very simple applications that can be done with one level of callback. I
find the "it works this way because its better" cult quite irritating. It
works that way because the #*(^#$&^ JS interpreter isn't multithreaded.

~~~
to3m
It wouldn't even need to be multithreaded, I don't thnik. You could have some
green threads-type system, using asynchronous I/O, a single-threaded server,
and something along the lines of Lua's yieldk. Have a new script spring into
life for each connection, suspend it when an I/O operation starts, and resume
it when the results are ready (or when something goes wrong). I think this
will be what Erlang does.

(I'm sure there are potential problems with this, but hopefully it would be
overall no worse than the current situation, while being easier to work with.)

------
hotBacteria
I found this document :
[https://github.com/kriskowal/q/tree/v1/design](https://github.com/kriskowal/q/tree/v1/design)
very helpful to understand how promises work behind the scene Also liked being
able to access the author's reasoning and the motivations behind his design
decisions

~~~
inglor
If you're going to mention Kris and concurrency, you better mention:
[https://github.com/kriskowal/gtor](https://github.com/kriskowal/gtor)

------
taternuts
TIL: fulfil vs fulfill [1]

1\. [http://grammarist.com/spelling/fulfil-
fulfill/](http://grammarist.com/spelling/fulfil-fulfill/)

~~~
bhrgunatha
The second nGram linked there (showing the rise of fulfill - with 2 l's in
American English)[1] seems to show that the increase in use of 2 l's started
around the same time as Noah Webster's dictionary was first published. [2]

I've always been fascinated why there is such a difference between spelling in
"British" and "American" English, I remember reading that the main reason was
Webster's dictionary and his desire to reform spelling according to
pronunciation. That Wikipedia article though quotes John Algeo: "He was very
influential in popularizing certain spellings in America, but he did not
originate them."

So now I'm as confused as ever. Why DID the spellings change so significantly.
I can accept that they took hold due to Webster's work, but I wonder why the
differences arose in the first place?

[1]
[https://books.google.com/ngrams/graph?content=fulfil%2Cfulfi...](https://books.google.com/ngrams/graph?content=fulfil%2Cfulfill&year_start=1800&year_end=2000&corpus=5&smoothing=3&direct_url=t1%3B%2Cfulfil%3B%2Cc0%3B.t1%3B%2Cfulfill%3B%2Cc0)

[2]
[https://en.wikipedia.org/wiki/Noah_Webster#Dictionary](https://en.wikipedia.org/wiki/Noah_Webster#Dictionary)

------
inglor
Another good classic about it is Domenic's you're missing the point of
promises at
[https://gist.github.com/domenic/3889970](https://gist.github.com/domenic/3889970)
from 2012

------
elchief
Stupid Cisco blocked this site on my corp network, due to "pornography",
assuming due to "lolita" in URL.

~~~
kuschku
Maybe you can load this? [https://archive.is/rQmhY](https://archive.is/rQmhY)

~~~
elchief
thanks!

------
sotojuan
I can't wait for async/await enough myself.

~~~
ilaksh
Just use babel.

------
benjaminjt
Nice summary! I wish I had this when I started getting into Promises a couple
of months ago.

For a really interesting look ahead to how Promises (and more!) might address
sync/async symmetry in ES6/7, check this out:
[https://youtu.be/DqMFX91ToLw](https://youtu.be/DqMFX91ToLw)

------
ilaksh
Really a lot more explanation than necessary. Get a feel by using them and
using a debugger or just console.log to trace execution. Then compare with
equivalent callback code and async/await with babel.

Then use async/await and look at node-modules.com to find modules that convert
to promises so you can use async/await.

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

~~~
Rusky
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.

~~~
rdtsc
It has regular threads but with appropriate data race safety guarantees. So
that won't help in context when large number of concurrent contexts are
happening, but perhaps it should first become a bottleneck and then solved,
because it might just be good enough.

------
spooningtamarin
They abide by the beautiful monadic laws.

~~~
jmcomets
When the event driven programming / promise hype started, I was like `Maybe $
exists thisConcept`

------
debacle
Maybe JavaScript isn't the best language to explain Promises in considering
how verbose they seem to be next to procedural code.

------
pjzedalis
This article has put me over the ledge of taking some time to really study Go.
Goroutines are starting to sound very attractive.

------
hosh
And here I thought someone besides Mark Burgess was writing on Promise
Theory...

------
anowlcalledjosh
Came expecting psychology, was disappointed.

