### Nested Callbacks, aka Call-back hell

Chaining callbacks, by nesting them into each other:

```javascript
setTimeout(() => {
  console.log("1")
  setTimeout(() => {
    console.log("2")
    setTimeout(() => {
      console.log("3")
    }, 1)
  }, 1)
}, 1)
```

Output:

```
1
2
3
```



```javascript
setTimeout(() => {
  console.log("1")
  setTimeout(() => {
    console.log("2")
    setTimeout(() => {
      console.log("2b")
    }, 2)
    setTimeout(() => {
      console.log("3")
    }, 1)
  }, 1)
}, 1)
```

The lexical structure is convoluted and will most likely not match the structure of the dynamic execution, e.g. the "2b" is logged later than the "3", even though it's position in the source code is before the "3". 

```
1
2
3
2b
```


### Simple Promise that resolves after a give time

Using Promises allows to transform code that would require deep nesting, into code that chains promises with in a flatter way:

```javascript
// promisification of a function that accepts callbacks
function wait(t) {
  return new Promise(resolve => {
    setTimeout(resolve, t)
  })
}

console.log("1")
wait(1).then(() => {
  console.log("2")
})
```

Chaining promises, by returning a new promise in a `then` handler

```javascript
console.log("1")
wait(1).then(() => {
  console.log("2")
  return wait(1)
}).then(() => {
  console.log("3")
})
```

Creating new promises without chaining, "3" does not "wait" on "2b"

```javascript
console.log("1")
wait(1).then(() => {
  console.log("2")
  wait(2).then(() => console.log("2b"))
  return wait(1)
}).then(() => {
  console.log("3")
})
```

output: 

```
1
2
3
2b
```

### With async / await syntax

Even though the structure of promises is flat, it contains a lot of clutter an at least one level of callbacks, because `then` uses callbacks itself. The `await` keyword removes indirection and allows to write asynchronous code that is as readable as normal code. 

The new `await` keyword is only valid in functions that are declared `async`, so we have to wrap them inside a `async () => { ... }` anonymous async function. 

```javascript
(async () => {
  console.log("1")
  await wait(1)
  console.log("2")
  await wait(1)
  console.log("3")
})()
```

The asynchronous cope lexical structure matches dynamic behavior match again.

```
1
2
3
```

### Problem: 

But, since the behavior is still executed by an event loop, other code can be executed in between. 

```javascript
// A
wait(0).then(async () => {
  console.log("A1")
  await wait(1)
  console.log("A2")
  await wait(1)
  console.log("A3")
})

// B
wait(0).then(async () => {
  console.log("B1")
  await wait(1)
  console.log("B2")
  await wait(1)
  console.log("B3")
})
```

The console contains log entries of both control flows `A` and `B`. Since the log messages are domain specific, it is easy to distinguish A from B

```
A1
B1
A2
B2
A3
B3
```

## Aysnc behavior with generic messages...

```javascript
async function genericCode() {
  console.log("1")
  await wait(1)
  console.log("2")
  await wait(1)
  console.log("3")
}

// A
console.log("A")
wait(0).then(() => genericCode())

// B
console.log("B")
wait(0).then(() => genericCode())
```

Some log entries in 

```
A
B
1
1
2
2
3
3
```


