Skip to content
DevMeme
293 of 7435
The 'Loss' Meme Implemented in JavaScript Promise Hell
Languages Post #350, on Apr 30, 2019 in TG

The 'Loss' Meme Implemented in JavaScript Promise Hell

Why is this Languages meme funny?

Level 1: And Then... Enough!

Imagine you’re listening to someone tell a story, and they just keep going “and then... and then... and then...” for every little thing they did. For example: “I woke up, then I brushed my teeth, then I walked ten steps to the door, then I went to the reception desk, then I talked to the receptionist, then I walked ten more steps, then I talked to the doctor, then...”. Eventually, you’d probably laugh and say, “Okay, that’s enough, we don’t need every single step!” This meme is doing the same thing, but with code. It shows a super long list of steps inside a computer program, each indented further like a big sideways staircase. It’s funny because the code is unnecessarily complicated – just like an overly detailed story – and it even jokes that “legal” (the rules or the grown-ups) said to stop before finishing the crazy chain of events. In simple terms, the picture makes us laugh at the idea of making something straightforward turn into a ridiculously long, step-by-step saga, until even the code itself says, “No more, this is just silly now!”

Level 2: Promise Chain Reaction

Let’s break this down in simpler terms. This code is written in JavaScript, and it’s dealing with something called a Promise. In JavaScript, a promise is like a ticket that says “I promise to give you a result later.” When that result is ready, you can then do something with it. You use the .then() method to say, “then run this next bit of code after the promise resolves.” If something goes wrong, you can catch the error with .catch().

Now, promises were introduced to make dealing with things that take time (like data from a server, or waiting for a file to load) easier to write and read. Before promises, we mostly used callbacks – basically passing a function into another function to run later. That often led to code looking like this:

doSomething(function(result1) {
    doNext(result1, function(result2) {
        doAnother(result2, function(result3) {
            // and so on...
        });
    });
});

Each time you needed the result of one async operation to start the next, you had to nest another function inside the callback. As you can see, the indent keeps increasing with every step – that’s what we call “callback hell” or the “pyramid of doom.” It becomes hard to read and maintain, because the code marches diagonally across the screen. It’s like a story that keeps saying “and then, and then, and then” – you lose track of where you started.

Promises help solve that by allowing us to chain actions one after another without piling them inside each other. Ideally, promise-based code is written like a straight line, not a pyramid. For example, if each of those move or go.to or talk.to functions returns a promise, you can do this:

move(10)
  .then(() => go.to(door))
  .then(() => move(10))
  .then(() => go.to(reception))
  .then(() => talk.to(receptionist))
  .then(() => move(10))
  .then(() => talk.to(doctor))
  .catch(error => {
    console.error("Something went wrong during the sequence:", error);
  });

This way, each .then() is chained to the previous one in a flat sequence. We don’t nest a new function inside each .then; instead we return a promise (like go.to(door)) and keep the chain going. The result is that our code stays at roughly the same indentation level, making it much easier to read from top to bottom. We also use a single .catch() at the end to handle any error from any of the steps in one place. In the snippet above, if any of those actions fails (throws an error or a rejection), the chain will jump to that final catch and log the error. That’s much cleaner than putting an empty catch after every step as in the meme – which, by the way, is a bad practice because it hides errors rather than handling them. In the meme’s code, each .catch() was empty, meaning errors would be swallowed silently. In a real program, that’s like disconnecting all the smoke alarms in your house – if a fire starts (an error), you’d never know until everything’s in flames.

By April 2019, when this was posted, JavaScript had an even nicer feature called async/await (introduced in ES2017). This feature is built on promises, but lets you write asynchronous code that looks almost like regular synchronous code. Using async/await, the example could be written in a style that avoids .then() chaining entirely:

async function doAllTheThings() {
  try {
    if (received(news)) {
      await move(10);
      await go.to(door);
      await move(10);
      await go.to(reception);
      await talk.to(receptionist);
      await move(10);
      await talk.to(doctor);
      // ... maybe something else, if it weren't "legally" stopped
    }
  } catch (error) {
    console.error("Sequence failed:", error);
  }
}

Here, the await keyword pauses the function until the promise settles, so the code can be written in a top-down manner without indenting further for each new step. Each await corresponds to a .then behind the scenes, but it feels like reading a normal sequence of instructions: move 10, then go to door, then move 10, then go to reception, etc. If any of those steps throws an error, the control jumps to the catch block at the bottom. This is exactly how we avoid the pyramid of doom in modern JavaScript – by writing asynchronous steps as if they were synchronous, which is more natural to follow.

Now, back to the meme content itself: it literally lists a chain of actions in a somewhat comical scenario (news received, walk 10 steps to the door, go to the reception, talk to receptionist, then move further, talk to doctor). This reads almost like a mini text adventure game or a bureaucratic procedure – you can imagine a character moving through an office building. It’s unusual to see such literal real-world steps in code; that’s part of the humor. It’s taking something very relatable (going to the doctor’s office) and expressing it in an over-complicated JavaScript way. The deep indenting of the code visually mirrors the idea of going deeper and deeper into this building (from door to reception to doctor’s room).

The kicker is the comment // I am legally not allowed to finish this joke. This is the author’s way of saying “this has gotten so out of hand, I better stop now.” It implies that extending the chain further would cross some line – possibly it would become inappropriate or literally involve lawyers. It’s a playful exaggeration: code editors don’t have legal officers giving you orders, of course, but the comment pretends that “Legal” (as in a company’s legal department) stepped in to shut down the fun. This could be referencing how some jokes can go into NSFW or risky territory, and someone might jokingly say, “Legal says I can’t continue.” Or it’s simply underlining that continuing this pattern would be so wrong that it should be illegal in the land of coding style guides. In any case, it’s a nod to the reader that the absurd chain won’t continue – we’ve reached the ultimate punchline by dragging “doctor” and “legal” into a programming joke.

For a junior developer or someone still learning JavaScript, the key takeaways are:

  • Avoid deep nesting with .then(): If you find yourself indenting further at each step while using promises, you’re likely doing it the hard way. Instead, return promises from inside .then() or use multiple .then() calls in a row as shown, so your code stays flat.
  • Use one .catch() for the whole chain (if appropriate): It often makes sense to handle errors in one place, rather than catching and ignoring them each time. Only catch earlier if you plan to recover from that specific error and continue.
  • Consider async/await: It can make asynchronous code much easier to read, as if you’re writing a simple sequence of steps. Just remember to wrap it in a try/catch to handle errors.
  • Recognize code smells: The term code smell means a hint in your code that something might be designed poorly. Extremely deep indentation and repeated empty catches are big code smells. They hint that the structure could be improved and that error handling is inadequate. A good rule of thumb: if your code starts to form a triangle shape at the margin, step back and rethink the approach.
  • Humor in code is okay (sparingly): The comment about legal not allowing the joke is, of course, just humor. While it’s generally best to keep actual production code serious and clear, within a meme or a lighthearted project, you’ll encounter these tongue-in-cheek comments. They’re there to make fellow devs smile and drive home the point in a memorable way. In this case, the humor helps us remember just how ridiculous that promise chain is.

In essence, this meme is a funny demonstration of JavaScript promise misuse. It teaches the lesson that just because you have a tool (promises) meant to make things better, you still need to use it correctly. Otherwise, you end up recreating the same mess (nested callbacks) with new syntax. And if your code starts needing a physician and a lawyer, you know you’ve taken a wrong turn!

Level 3: The Pyramid of Doom

This meme dives straight into JavaScript’s asynchronous abyss. The code snippet is an exaggerated example of a promise chain gone wild – a modern twist on the infamous callback hell. In theory, Promises were designed to rescue developers from deeply nested callback functions, making asynchronous code flatter and more readable. But here we see the exact opposite: each .then() is stacked inside another like a Russian nesting doll, creating a triangular shape often nicknamed the “pyramid of doom.”

For experienced developers, this screenshot triggers flashbacks. It’s a satire of real-world code smells where someone chains one asynchronous action after another in a naive way. Each level of indentation represents yet another step that only runs after the previous one succeeds. By the time we’ve indented to call talk.to(doctor), the code is so far to the right it’s practically off the screen. The humor comes from the absurdity of this structure – Promises were supposed to prevent such arrow-shaped code, yet here we are, climbing Mount Indentation. It’s like inventing a hoverboard and then insisting on adding wheels to it anyway.

Let’s unpack the scenario depicted in code:

  • It starts with if (received(news)) { ... }, meaning some news was received. Inside that, the code calls move(10), presumably an async function that moves some character or cursor by 10 units.
  • Then .then(() => { ... }) is attached, meaning after moving 10 steps, it will execute the next function. Instead of chaining .then calls one after the other, this code nests them. So inside the first .then, it calls go.to(door), then attaches another .then() inside that callback.
  • This pattern continues: go to the door, then move 10 steps further, then go to reception, then talk to the receptionist, then move 10 again, then finally talk to the doctor. Each action is wrapped in an arrow function () => { ... } passed to the previous .then(). The indentation grows with each step, forming a steep sideways ladder.

From a senior perspective, a few things stand out as hilariously realistic horrors:

1. Misusing Promises: The coder here is using promises in the most convoluted way possible. Instead of returning a promise in each .then and chaining them, they’re nesting each subsequent call. This technically works, but it defeats the purpose of promise chaining. It resembles old-school Node.js callback patterns, just with then() instead of raw callbacks. Any seasoned JS developer knows you can rewrite this as a flat chain (or better, with async/await) without all the extra indent. Seeing a promise chain written like this is like seeing someone use a futuristic self-driving car to tow a horse carriage – yes, it moves, but why would you do that?

2. The “Callback Hell” Aesthetic: Visually, the code is a textbook case of callback hell, also called the Christmas tree problem or arrow anti-pattern. The nested braces and indentations form an arrow shape pointing inward, which we jokingly call the pyramid of doom. This meme exaggerates it to an absurd extent, where the “pyramid” has so many levels that it walks right into a clinic waiting room. For developers who lived through the early days of Node.js (with functions inside functions inside functions), this image is both funny and slightly traumatic. We’ve spent late nights refactoring code that looked like this, carefully unravelling the tangle of ).then(() => { ... }).catch() blocks to make it sane.

3. Lack of Proper Error Handling: Notice every .then() is followed by an empty .catch(). Those catch blocks are just }).catch(); with nothing inside. This means if any step fails, the error is caught and silently ignored at that level. In other words, errors vanish without a trace – no logging, no handling, nothing. This is a code quality nightmare because if something goes wrong (like talk.to(doctor) throws an exception), the code will catch it and then do nothing. The problem won’t propagate or get fixed; it’ll just fail quietly. In a real application, that’s how bugs slip by or data gets lost without explanation. Seeing multiple empty catches is a giant red flag. It’s humorous in the meme because it shows the developer was so focused on chaining these ridiculous steps that they didn’t even bother to handle errors properly, effectively sweeping problems under the rug at every stage. It’s as if each department in this “office visit” promised not to report any issues up the chain – a recipe for disaster.

4. Escalating Narrative to Absurdity: The content of the actions forms a little story: receive news, walk 10 steps, go to the door, walk 10 steps, go to reception, talk to receptionist, walk 10 steps, talk to doctor… It’s mundane tasks, but chained like an epic quest. By the time we get to the doctor, the scenario has escalated from a simple “received news” to a full-on doctor’s appointment. This escalation is inherently funny – we don’t expect a code snippet to read like a set of real-life errands. It’s poking fun at how over-complicated and drawn-out the sequence became. It’s as if the code itself turned into a mini adventure story for something that probably should have been straightforward.

5. “Legally not allowed to finish” – Meta Humor: The punchline is the green comment at the deepest level:

// I am legally not allowed to finish this joke

This comment breaks the fourth wall of the code. Why would a code comment mention legal permission? It’s a joke about the joke. The author implies that continuing the promise chain narrative would violate some (imaginary) law or policy. This is a playful exaggeration, suggesting the chain has become so ridiculous or potentially edgy that the company’s lawyers intervened. There’s an undercurrent of parody here: sometimes in corporate environments, developers include funny comments or have to be careful about what they write publicly. Saying “legally not allowed to finish” satirizes the idea that maybe the next steps were going to reference something inappropriate (or a well-known punchline that Legal flagged). It could also allude to the common comedic trope: “if it lasts too long, seek medical help,” which is often followed by “and if it goes even longer, well, lawyers get involved.” The code literally reached a doctor, so the next escalation might have been something truly over-the-top – but the author cuts it off with a mock legal gag. For a seasoned developer, the sheer randomness of a legal disclaimer inside a deeply nested promise is comedy gold. It’s mixing contexts in a nonsensical way: we started with code about moving to a door and ended with an attorney forbidding further humor. It underlines just how off-track this “promise chain” has gotten.

6. The Real Lesson – Use Better Methods: Technically, this meme is a tongue-in-cheek reminder of how not to structure asynchronous code. By 2019 (the date on the post), JavaScript had modern tools to avoid this mess. Any senior dev reading this would think, “Just use async/await or at least return your promises!” The industry had largely moved on from stacking .then() callbacks like this. In fact, most linters and coding standards by then would strongly discourage such nesting. This code would get you some raised eyebrows (and probably a stack of code review comments) from colleagues. The joke hits close to home because many of us have refactored code that looked eerily similar – perhaps written by someone new to asynchronous programming or converting from synchronous thinking.

In summary, at a senior level the meme is both a crack-up and a cautionary tale. It humorously exaggerates a code quality issue every experienced JavaScript developer knows well. The “pyramid of doom” shaped by those indents is a sight we’d prefer never to see in real projects, and the over-the-top narrative ending in a doctor’s office and legal intervention just highlights how absurd letting a promise chain grow unchecked can be. It’s a nod-and-laugh moment: we’ve all seen then-chains or callback chains that got out of hand, and this one takes the cake (with extra layers). The meme cleverly wraps a software engineering lesson (don’t nest promises like this) in a layer of ridiculous humor (doctor visits and lawyer jokes), making it memorable for anyone who’s battled bad code.

Description

A screenshot of a code editor with a dark theme displays a snippet of JavaScript code. The code is structured as a deeply nested series of `.then()` calls on what appears to be a Promise, creating a visual 'pyramid of doom' or 'callback hell' that indents progressively to the right. The code tells a story through function calls: `if (received(news))`, `move(10)`, `go.to(door)`, `go.to(reception)`, `talk.to(receptionist)`, and finally `talk.to(doctor)`. In the most deeply nested block, a comment in green text reads, '// I am legally not allowed to finish this joke'. The entire structure is a clever, high-context joke representing the four-panel internet comic 'Loss' through asynchronous JavaScript operations. The 'pyramid of doom' itself is a well-known anti-pattern in older JavaScript, which has since been largely solved by `async/await`. The punchline is the comment, which both acknowledges the meme's controversial status and mimics the wordless final panel

Comments

8
Anonymous ★ Top Pick This is what happens when you don't use async/await. Your entire codebase becomes a tragic four-act play about loss, with no resolution in the final `catch` block
  1. Anonymous ★ Top Pick

    This is what happens when you don't use async/await. Your entire codebase becomes a tragic four-act play about loss, with no resolution in the final `catch` block

  2. Anonymous

    Legal wanted an audit trail, so we ditched async/await for a 10-level .then() pyramid - now every stack trace doubles as an affidavit

  3. Anonymous

    The real pyramid scheme was convincing an entire generation of developers that callbacks were a reasonable way to handle async operations, then selling them Promises as the solution, only to deprecate those for async/await two years later

  4. Anonymous

    The real error handling here is the comment - everything else just resolves to deeper indentation until the linter calls the doctor itself

  5. Anonymous

    This code perfectly captures the evolution of JavaScript async patterns: we escaped callback hell only to build promise purgatory. The comment 'I am legally not allowed to finish this joke' is the real punchline - because by the time you've nested this deep, the original context is lost in a stack trace somewhere between the receptionist and the doctor. Modern async/await exists specifically so we never have to write (or review) code that looks like a sideways Christmas tree again. The nine consecutive .catch() blocks are the developer's way of saying 'I give up' in nine different ways

  6. Anonymous

    When your workflow engine is nested then()s, you’ve built a HIPAA‑compliant Pyramid of Doom - use async/await or a saga before your error budget files malpractice

  7. Anonymous

    Nested catches so deep, even the stack trace needs its own try-catch to unwind

  8. Anonymous

    That Promise chain reads like an ER intake - door → receptionist → doctor → a staircase of empty catch()s; callback hell with malpractice insurance. Use async/await and one error boundary to do triage in five lines

Use J and K for navigation