Skip to main content
Home  ›  Blog

JavaScript: Promises are GOTO evil incarnate

All programmers know that GOTO was evil. It was a thing in the early days of code, but things always got out of hand once the code got larger. Now we're repeating the exercise with JavaScript promises.

The Rise and Demise of GOTO

So let's quickly review why GOTO felt good:

  1. It looked simple
  2. It allowed us to move the program to a different position - and structure our work around that idea
  3. It was very flexible - we could GOTO anywhere we wanted
  4. It helped us think the way the CPU worked

The evil started, because:

  1. GOTO-Architecture is infectious, meaning once you start, other parts of the program must follow the same paradigm
  2. large programs (a few thousand lines) had a lot of jump-targets to GOTO
  3. after a while, your program would jump to a position after changing it's (global) state to something you didn't expect
  4. then after another while, something would break
  5. …and it was really hard to figure out why
  6. …and even harder to fix, as everything was very inter-dependent

Programmers had started with a simple solution, which just didn't scale - and ran into GOTO Hell. We were rescued by procedures, and later things got even more organized as we stuck the procedures into objects. This allowed programmers to set boundaries between what-is-allowed and what-is-not-allowed, resulting in more organization, helping us write 10x more code and still keep (kind of) tidy.

Since then we avoid GOTO Hell. Until now.

The Rise and Demise of Promises

I wrote my first AJAX application in 1998 when browsers didn't even support the concept yet. I had to use nasty tricks with Iframes doing server requests, starting timers to wait for the result and parsing the resulting XML/HTML to then generate new HTML in front of the user. That was hacky and so difficult, that it could never become mainstream. AJAX really took off when jQuery brought along a simple solution based on promises - albeit using a slightly different setup. 

Promises felt good, because:

  1. It looked simple
  2. It allowed us to wait in the program for something else to happen - and structure our work around that idea
  3. It was very flexible - we could Promise anything we wanted
  4. It helped us think the way the delayed HTTP worked

The evil started, because:

  1. Promise-Architecture is infectious, meaning once you start, other parts of the program must follow the same paradigm 
  2. large programs (a few thousand lines) had a lot of promises
  3. after a while, your program would have to sync callbacks, click-events, show/hide events and caused states you didn't expect
  4. after a while, the programs would break
  5. …and it was really hard to figure out why
  6. …and even harder to fix, as everything was chained and very inter-dependent 

Programmers had started with a simple promise - perfect to simply wait a bit for data to arrive. But it too doesn't scale - we're now in Callback Hell. We are being rescued by Observables (read: What Promises Do That Observables Can't) - but most developers have no clue why this is important. And the next evolution is already here as well - Reactive Programming (check out ReactiveX) will get us even more organized. Note that this is not the React JS view engine, but it is the foundation of the flux/redux architecture. This allows us to set clear structures of data-flow and events, resulting in clean architectures and most likely one-way data flows, helping us write 10x more code and still keep things tidy.

This will help us get out of Callback-Hell, but it does mean we have to wrap our head around this somehow. And we must start now. To be continued...

Love from Switerland,
iJungleboy

PS: In case you thought JavaScript Async/Await will save you instead, you are clearly mistaken. It's just a nicer syntax, but in the end it doesn't scale past "let my program wait for one event". But modern solutions are way beyond that problem - we have many events and data-changes happening out of sync. With Async/Await you're still stuck with the problem of events happening out of sync, so you must really look into Reactive Programming and Observables.


Daniel Mettler grew up in the jungles of Indonesia and is founder and CEO of 2sic internet solutions in Switzerland and Liechtenstein, an 20-head web specialist with over 800 DNN projects since 1999. He is also chief architect of 2sxc (see github), an open source module for creating attractive content and DNN Apps.

Read more posts by Daniel Mettler