DEV Community

Cover image for Merge Functions
Drew
Drew

Posted on • Updated on

Merge Functions

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
Let's get the exact description from MDN:

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. 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")
})
Enter fullscreen mode Exit fullscreen mode

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()
  }
}
Enter fullscreen mode Exit fullscreen mode

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 ");
});
Enter fullscreen mode Exit fullscreen mode

Try using this code all combined code.

By initializing the variable cancelBoth and assigning it the value of timePass_or_eventHandle, we actually cause the function to execute.
clickTickGif

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 to help make our function wrapping a bit more concise and readable.

Top comments (0)