Merge Functions
Published: 2021-01-22 11:08:24

Part of a series to track the 90-Day Beat Down

I recently got hired for a new gig. They hired 2 of us on a 90-day prove-yourself contract. Pretty sure this is a "competition" of sorts to see which of us can rise to the top.

This is how I internalize things I review and learn.

## Let's Combine Multiple Async Behaviors

### Async
Wait- what's an async behavior? 
![sink](https://dev-to-uploads.s3.amazonaws.com/i/i5wpxq9jo270ectsr37t.jpg)
Let's get the exact description from [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function):
> Async functions can contain zero or more await expressions. Await expressions suspend progress through an async function, yielding control and subsequently resuming progress only when an awaited promise-based asynchronous operation is either fulfilled or rejected. The resolved value of the promise is treated as the return value of the await expression. Use of async / await enables the use of ordinary try / catch blocks around asynchronous code.

What does that even mean? It's basically a giant game of redlight, greenlight. 
- Do something
   - **red light!**  
   - ...waiting for completion...
   - **green light!** 
- Do the next thing
  - **red light!**
  - ...waiting for completion...
  - **green light!**
- Do the next thing, etc. 

Now let's [think back to post 1](https://dev.to/dhack/upskill-for-the-day-job-25o8). Our goal was to do a better job of writing customizable, reusable functions by a) returning functions from functions and b) using functions as parameters (providing *listeners* or *callbacks*). 

Let's take a look at a lot of code. Go slowly, review this chunk, and see if you notice any patterns: 
```
let addOneListener = (selector) => (eventType) => (listener) => {
  let element = document.querySelector(selector);
  element.addEventListener(eventType, listener);

  return () => {
    element.removeEventListener(eventType, listener);
  };
};

let createTheInterval = (time) => (listener) => {
  let id = setInterval(listener, time);
  return () => {
    clearInterval(id);
  };
};

let addBtnListener = addOneListener("#button");
let addBtnClickListener = addBtnListener("click");

let oneSec = createTheInterval(1000);

let cancelOneSecond = oneSecond(() => {
  console.log("one")
})

cancelOneSecond()

let twoSeconds = createInterval(2000)
twoSeconds(() => {
  console.log("two")
})
```
We have ^^^ a number of functions that all **expect to receive a *listener* as a parameter**.

Now that we see this pattern, we can start combining functions in interesting ways. 

### Broadcasters (accepting the listeners)

I'm going to refer to functions that accept listeners as broadcasters, because that's how I was taught. You may also hear these named *sources* or other words that describe **things that push out values**. For now, a broadcaster is a function that accepts a listener. 
```
let comboFunction = (broadcaster1, broadcaster2) => listener => {
  let cancel1 = broadcaster1(listener)
  let cancel2 = broadcaster2(listener)

  return () => {
    cancel1()
    cancel2()
  }
}
```
This is a lot of code (again), so let's break it down: 
- `comboFunction` is a variable that is declared
- we initialize this variable and assign it the value of a function declaration
- that function accepts 2 additional functions as parameters (our *broadcasters*)
- our function **is** a variable until we decide to execute it like so: 
```
let timePass_or_eventHandle = comboFunction(addBtnClickListener, oneSec);
let cancelBoth = timePass_or_eventHandle(() => {
  console.log("time pass or event happened ");
});
```
[Try using this code all combined code](https://codesandbox.io/s/comboasyncpractice-bxux6). 

By initializing the variable `cancelBoth` and assigning it the value of `timePass_or_eventHandle`, we actually cause the function to execute. 
![clickTickGif](https://media.giphy.com/media/gPemXeO9J2wEMMmz4T/giphy.gif)

 What happens if we add `cancelBoth();`

Nothing! The "time pass" doesn't reach the console and the clicked button does nothing as well. 

Next time we can add in some [awesome lodash functionality](https://lodash.com/docs/4.17.15#curry) to help make our function wrapping a bit more concise and readable.