Why async code is so damn confusing (and a how to make it easy)
Tags: programming, javascript, async, mojiscript
Published: 2018-09-24 17:58:36

---
title: Why async code is so damn confusing (and a how to make it easy)
published: true
description: 
tags: programming, javascript, async, mojiscript
---

[![Yarn](https://thepracticaldev.s3.amazonaws.com/i/co055rex5v9goaqkuti5.jpg)](https://pixabay.com/en/yarn-kordonek-weave-sewing-model-3219436/)

Why is asynchronous code in Javascript so complicated and confusing? There are no shortage of articles and questions from people trying to wrap their bean around it.

Some handpicked questions from SO...

- [What is the JavaScript version of sleep()?](https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep)

- [JavaScript sleep/wait before continuing](https://stackoverflow.com/questions/16873323/javascript-sleep-wait-before-continuing)

- [Is there a Sleep/Pause/Wait function in JavaScript?](https://stackoverflow.com/questions/7854820/is-there-a-sleep-pause-wait-function-in-javascript)

- [Sleep in JavaScript - delay between actions](https://stackoverflow.com/questions/758688/sleep-in-javascript-delay-between-actions)

There are literally hundreds of questions and articles about async and a lot of them sound something like this:

```javascript
// How do I do this in JavaScript?
action1();
sleep(1000);
action2();
```

This is a common misunderstanding of how JavaScript works.

# Dirty hacks to force Sync

There are even dirty hacks to force sync

{% twitter 1043194634338324480 %}

**NOT RECOMMENDED**

# The problem is not Asynchronous code

I spend a lot of time thinking about Javascript and one of these times I had a silly thought. What if the problem is not asynchronous code. **What if the problem is actually the synchronous code?**

Synchronous code is the problem? WAT?

I often start writing my code synchronously and then try to fit my async routines in afterwards. This is my mistake.

**Asynchronous code cannot run in a synchronous environment.** But, there are no problems with the inverse.

![async/async feature chart](https://thepracticaldev.s3.amazonaws.com/i/44chigz6jmnk4el9ctbg.png)

This limitation is only with synchronous code!

![Mind blown GIF](https://media.giphy.com/media/xT0xeJpnrWC4XWblEk/giphy.gif)

# Write Asynchronously from the start

Coming to this realization, I now know that I should begin my code asynchronously.

So if I were to solve the async problem again, I would start it like this:

```javascript
Promise.resolve()
    .then(() => action1())
    .then(() => sleep(1000))
    .then(() => action2())
```

or with `async` and `await`...

```javascript
const main = async () => {
  action1()
  await sleep(1000)
  action2()
}
```

The `Promise` solution is... wordy. The `async/await` is better, but it's just syntactic sugar for a Promise chain. I also have to sprinkle `async` and `await` around and hope I get it right.

Sometimes `async/await` can be confusing. For example: These two lines do completely different things.

```javascript
// await `action()`
await thing().action()

// await `thing()`
(await thing()).action()
```

And then there's the recent article from [Burke Holland](burkeholland):

> [[DEV.to] Async/Await and the forEach Pit of Despair](https://dev.to/burkeholland/asyncawait-and-the-foreach-pit-of-despair-2267).

# What if there was no difference?

So I start to think again... What if there was no difference between async and sync code? What if I could write code without worrying about whether the code I am writing is asynchronous or not. What if async and sync syntax was identical? Is this even possible?

Well, that means I cannot use standard functions as they are only synchronous. `async/await` is out too. That code just isn't the same and it comes with it's own complexities. And promises would require me to write `then`, `then`, `then` everywhere...

So again, I start thinking...

# Asynchronous Function Composition

I love love love functional programming. And so I start thinking about asynchronous function composition and how I could apply it to this problem.

In case this is your first time hearing about function composition, here's some code that might help. It's your typical (synchronous) "hello world" function composition. If you want to learn more about function composition, read this article: [Functional JavaScript: Function Composition For Every Day Use](https://hackernoon.com/javascript-functional-composition-for-every-day-use-22421ef65a10).

```javascript
const greet = name => `Hello ${name}`
const exclaim = line => `${line}!`

// Without function composition
const sayHello = name =>
  exclaim(greet(name))

// With function composition (Ramda)
const sayHello = pipe(
  greet,
  exclaim
)
```

Here I used [`pipe`](https://ramdajs.com/docs/#pipe) to compose `greet` and `exclaim` into a new function `sayHello`.

Since `pipe` is just a function, I can modify it to also work asynchronously. Then it wouldn't matter if the code was synchronous or asynchronous.

One thing I have to do is convert any callback-style function to a promise-style function. Fortunately node's built in `util.promisify` makes this easy.

```javascript
import fs from 'fs'
import { promisify } from 'util'
import pipe from 'mojiscript/core/pipe'

// Synchronous file reader
const readFileSync = fs.readFileSync

// Asynchronous file reader
const readFile = promisify(fs.readFile)
```

Now if I compare a Synchronous example with an Asynchronous example, **there is no difference**.

```javascript
const syncMain = pipe([
  file => readFileSync(file, 'utf8'),
  console.log
])

const asyncMain = pipe([
  file => readFile(file, 'utf8'),
  console.log
])
```

This is exactly what I want!!!

Even though `readFileSync` is synchronous and `readFile` is asynchronous, the syntax is exactly the same and output it exactly the same!

I no longer have to care what is sync or what is async. I write my code the same in both instances.

[![Banana says Wooo-Wooooo!](https://thepracticaldev.s3.amazonaws.com/i/uz5dvo3z5raeg0vt797l.png)](http://worldartsme.com/hooray-clipart.html)

# ESNext Proposal: The Pipeline Operator

It is worth mentioning the [ESNext Proposal: The Pipeline Operator](https://github.com/tc39/proposal-pipeline-operator).

The proposed pipeline operator will let you "pipe" functions in the same way `pipe` does.

```javascript
// pipeline
const result = message =>
  message
    |> doubleSay
    |> capitalize
    |> exclaim

// pipe
const result = pipe([
  doubleSay,
  capitalize,
  exclaim
])
```

The format between the `Pipeline Operator` and `pipe` are so similar that I can also switch between the two without any problems.

The Pipeline Proposal is very exciting, but there are two caveats.

1. It's not here yet, and I don't know _if_ or _when_ it will come or _what_ it will look like. babel is an option.
2. It does not (yet) support `await` and when it does, will most-likely require different syntax to pipe sync and async functions. yuck.

I also still prefer the `pipe` function syntax over the pipeline operator syntax.

Again, the pipeline will be starting code synchronously, which I have already identified as a problem.

So while I am excited for this feature, I may never end up using it because I already have something better. This gives me mixed feelings :|

# MojiScript

This is where you ask me what the heck is this...

```javascript
import pipe from 'mojiscript/core/pipe'
//                ----------
//               /
//          WAT?
```

(Okay you didn't ask... but you're still reading and I'm still writing...)

[MojiScript](https://github.com/joelnet/MojiScript) is an **async-first**, opinionated, functional language designed to have 100% compatibility with JavaScript engines.

Because MojiScript is async-first, you don't have the same issues with async code that you do with typical JavaScript. As a matter of fact, async code is a pleasure to write in MojiScript.

You can also import functions from MojiScript into existing JavaScript applications. Read more here: https://github.com/joelnet/MojiScript

# MojiScript Async Examples

Here's another great example of async with MojiScript's `pipe`. This function prompts a user for input, then searches the [Star Wars API for](https://swapi.co) using [Axios](https://github.com/axios/axios), then writes the formatted results to the console.

```javascript
const main = ({ axios, askQuestion, log }) => pipe ([
  askQuestion ('Search for Star Wars Character: '),
  ifEmpty (showNoSearch) (searchForPerson (axios)),
  log
])
```

If this has made you curious, check out the full source code here: https://github.com/joelnet/MojiScript/tree/master/examples/star-wars-console

# I need your help!

Here's the part where I ask you for help. MojiScript is like super brand new, pre-alpha, and experimental and I'm looking for contributors. How can you contribute? Play with it, or submit pull requests, or give me your feedback, or ask me questions, anything! Head over to https://github.com/joelnet/MojiScript and check it out.

# Summary

- Asynchronous code cannot run in a synchronous environment.
- Synchronous code will run just fine in an asynchronous environment.
- Start writing your code asynchronously from the start.
- `for` loops are synchronous. Get rid of them.
- Try asynchronous function composition with something like [`pipe`](https://github.com/joelnet/MojiScript).
- [`pipe`](https://github.com/joelnet/MojiScript) has similar functionality as the ESNext Pipeline Proposal, but available today. 
- Play with [MojiScript](https://github.com/joelnet/MojiScript) :)
- MojiScript is currently in the experimental phase, so don't go launching this into production yet!

[Getting started with MojiScript: FizzBuzz (part 1)](https://dev.to/joelnet/getting-started-with-mojiscript-fizzbuzz-part-1-2fji)

Read more articles by me on [DEV.to](https://dev.to/joelnet) or [Medium](https://medium.com/@joelthoms).

Follow me on Twitter [@joelnet](https://twitter.com/joelnet)

![Cheers!](https://thepracticaldev.s3.amazonaws.com/i/md1oj03uisp93k36ekup.jpg)