Dissecting explanations of Javascript Promises

Posted on Thu 09 February 2023 in IT, meta

What is a Javascript Promise? When I was documenting the Neo4j Javascript driver, I did not know. So let's find out, and in so doing tear to pieces explanations I found online. My favorite past time.

W3Docs

In JavaScript, a promise is a unique object linking the "producing code" and the "consuming code". In other words, it is a "subscription list".

Three pairs of quotes, but okay. A unique object? Adjectives are not ornamental christmas balls, so how does this unique object would compare to a ... non-unique object? What is a producing code and a consuming code? If you think I know already what they are, then you should also know that I would not be reading this page in that case. 80% of the readers will not know what those are, so you cannot give those concepts for granted. And no, the solution is not to open the page with definitions. There is nothing worse than going through a glossary in a technical page.

The "producing code" takes the time it needs to produce the promised result, and the promise makes the result available to the overall subscribed code whenever it's ready.

I still don't know what a "producing code" is. And then the biggest flaw of all: using the word you are defineing to explain that same word. I still don't know what a promise is, and here are we talking about promised result. And what is "the overall subscribed code"? I have no idea. When does it get ready? How do I make it so?

But, JavaScript promises are more complicated that the described simple subscription list: there are additional features and limitations inside them. Let's start at the very beginning.

Comma after a leading conjunction, two bold moves. And the whole sentence is just a bullshit filler, saying "promises are complicated! You need an explanation". Gotcha. Thank you. That's why I'm here, but three paragraphs in and I'm still clueless. And also, your time is up: I'm leaving. But let's look at one more sentence that reassures me that I am not losing anything by leaving:

The arguments of it [the function], such as the resolve and reject, are considered callbacks provided by JavaScript.

And here we get the final confirmation that the writer doesn't know what the words they are writing are about. "Are considered"? A callback is a callback. It's like saying "the time on your train ticket is considered to be the departure time". No, it is. Is this written by somebody that really understands promises? Hard to tell.

A quick sum-up of the flaws:

  • lots of concepts given for granted
  • using the word promise to describe what a promise is
  • using language at random: sentences that don't really say anything valuable, adjectives used to make sentences less dry, punctuation not accurately set.

javascript.info

This one starts much better. It starts with an analogy:

Imagine that you're a top singer, and fans ask day and night for your upcoming song. To get some relief, you promise to send it to them when it's published. You give your fans a list.

This is great, I know how singers work, roughly. It doesn't need a lengthy explanation. And, cherry on top, it uses promise with the meaning it has in natural language, before the Javascript overloading.

  1. A "producing code” that does something and takes time. For instance, some code that loads the data over a network. That’s a "singer”.
  2. A "consuming code” that wants the result of the "producing code” once it’s ready. Many functions may need that result. These are the "fans”.
  3. A promise is a special JavaScript object that links the "producing code” and the "consuming code” together. In terms of our analogy: this is the "subscription list”.

I'm still not totally onboard, but it makes a lot of sense so far, so I feel like I'm ready to see a code example and be able to parse it out somehow. I need to read through a filler first though:

The analogy isn't terribly accurate, because JavaScript promises are more complex than a simple subscription list: they have additional features and limitations. But it’s fine to begin with.

Of course it's not accurate: it's an analogy. And that's fine. No physics professor think that water flows are an accurate analogy for electrical currents, but it would be idiotic to not use it. If it aids understanding, it should be used. Of course you cannot use it forever: at some point you have to ditch the analogy and face the harsh truth of electromagnetic fields. They are a new concept, but you can think of them as a 3D something that you know, and it's easier and less intimidating. Ditching analogies for fear of coming out as "not-expert" is wrong. (It does need to aid understanding though. If you have to explain the analogy in detail, it's probably not a good one.)

Anyway. The page then continues with text of mediocre quality, but it is filled with enough technical details spelled out well enough to actually be clear. When the writers forgets that he has to fill a page, he can write coincise sentences that get good content across:

So to summarize: the executor runs automatically and attempts to perform a job. When it is finished with the attempt, it calls resolve if it was successful or reject if there was an error.

developer.mozilla

This is quite different. One thing is clear: you may disagree with how content is laid out, but you can see that there's been thought from somebody that deeply understood what he was talking about. Notice how every word is carefully laid down in the very first sentence:

A Promise is an object representing the eventual completion or failure of an asynchronous operation.

Notice how it's all words you most likely know already (or you should). Then comes a disclaimer that is quite opaque to a newcomer, but makes a lot of sense.

Since most people are consumers of already-created promises, this guide will explain consumption of returned promises before explaining how to create them.

They flip the exposition. Both previous pages started showing how to create a promise, but what do I care. 80% of people are looking up promises because they were using whatever library, got a weird object returned, checked the type, and found out it was a promise. It makes a lot of sense to flip the exposition so that you are first exposed to how to deal with a promise! It makes it more pedagogical, and relevant to the reader.

Essentially, a promise is a returned object to which you attach callbacks, instead of passing callbacks into a function.

Three sentences in, and I still have no questions. Everything is clear. And now comes the first example. It shows how you would do something without promises, and how you would translate the same thing into using promises. It is saying: "here is what you know already. Now here is how you expand it with this other concept." And then it tells why you should care:

In the old days, doing several asynchronous operations in a row would lead to the classic callback pyramid of doom. With promises, we accomplish this by creating a promise chain. [example]

And then it digs deeper. What's the syntax like in the general case. How do you chain them. What are the common mistakes. Error handling. And more. But it's tidy. They don't assume you know something until they have covered it, and they don't show off their knowledge of terms. They pick an entry point (and picking one is a skill) and work from there in a pedagogical way.

Grafana exemplars

I landed here by pure chance, cause a collegue started working there, but let's read through. This is the very first page of their documentation. It starts with:

An exemplar is a specific trace representative of measurement taken in a given time interval.

I have absolutely no idea of what this sentence means. I can see that the words are carefully laid down, but it's not words I am familiar with. In the Mozilla page, you could assume that 80% of the audience knew every single word of the opening sentence, but here? What is a trace? What makes it specific? What is a measurement? And how do I take a measurement into a trace? I am completely lost.

While metrics excel at giving you an aggregated view of your system, traces give you a fine grained view of a single request;

What are metrics? What are traces? Mind you, this is the first real docs page, the first under Fundamentals and after the Introduction to Grafana (which is just an intro to the different versions).

exemplars are a way to link the two.

Ok, so exemplars, which I know nothing about, are a way to link metrics, which I know nothing about, with traces, which I know nothing about. That's 46 words that have not led me one inch closer to knowing what the product is, and no links or tooltips either.

Now. The next paragraph switches gears completely:

Suppose your company website is experiencing a surge in traffic volumes. While more than eighty percent of the users are able to access the website in under two seconds, some users are experiencing a higher than normal response time resulting in bad user experience.

Oh, here comes a use-case. I understand web traffic, so this should help me in clarifying exemplars. Except that I read, and I am puzzled. When system load is high, all users experience "a higher than normal response time". It's not like 80% get a timeout and 20% get a blizzard experience. So the only use case presented in the first Fundamentals page is... inaccurate?

Use exemplars to help isolate problems within your data distribution by pinpointing query traces exhibiting high latency within a time interval.

Here is a packed sentence saying that these exemplars will help me in this use-case. It still doesn't tell me how. It doesn't show me how. However, it doesn't miss the chance of saying that "Support for exemplars is available for the Prometheus data source only." What is a Prometheus data source? What do I care about this piece of information?

I can see many people were involved in writing this page, and a frankenstein came out. Somebody said: we need to have a precise definition [of what?] as opening. Somebody else said: we need to have a practical example. Yet somebody else said: we need to puntualize that this feature doesn't always apply. But nobody was bold enough to take one decision, and all ideas were diplomatically accepted. The result is that the page has no direction, and the reader experience is neglected in favor of not pissing anybody off.

Google Analytics 4 migration

I have a chip on my shoulder with Google Analytics, so I have a hard time holding my temper. But let's try. I'm much more annoyed at the API itself rather than the docs, to be honest.

Indeed, the page itself is not too bad. My main complaint is about the number of links. They send you everywhere, confusing you as to what you should be reading to achieve your goal, and nowhere at the same time, because a third of them are 404s. And information is scattered across all these pages, all with a vaguely similar title, and after you jump a couple links and end up with 10 open tabs that kinda look the same, you start wondering: what the hell should I be reading?

The Data API v1 client libraries were designed to get you started fast. By default, client libraries try to automatically find your service account credentials.

Who would design libraries to get you started slow?