TypeOfNaN

What is a Thunk?

Nick Scialli January 31, 2020🚀 3 minute read

“Thunk” is one of those programming terms that sounds intimidating, but many of us are actually familiar with and have used them. Let’s first see how Wikipedia defines thunks[1]:

In computer programming, a thunk is a subroutine used to inject an additional calculation into another subroutine. Thunks are primarily used to delay a calculation until its result is needed, or to insert operations at the beginning or end of the other subroutine.

This offers a little help, but maybe is a little too abstract.

So, what is a thunk really? It’s simply a function returned from another function. Let’s look at a quick example in JavaScript:

function delayedLogger(message, delay) {
  return function(logger) {
    setTimeout(function() {
      logger(message);
    }, delay);
  };
}

In this example, when we call the delayedLogger function, it returns a thunk. We can then pass that thunk a logger parameter, which will be executed after the specified delay.

const thunk = delayedLogger('See you in a bit', 2000);
thunk(console.log);

In this example, we’ll see "See you in a bit" logged to the console after two seconds.

Bonus: Use in Redux

If you’re familiar with Redux, you likely know the concept of action creators: functions that return action objects. The following is an example of an action creator that makes an action that adds a product to a shopping cart:

function addToCart(product) {
  return {
    type: 'ADD_TO_CART',
    payload: product,
  };
}

It turns out that we need a little more flexibility with our action creators: we need to be able to dispatch an action asynchronously: often after we perform a fetch request to save or load data from an API. We can solve this issue by using redux-thunk, a Redux middleware that allows us to return thunks from action creators [2].

Let’s mock up what this would look like. We’ll load a list of products from an API and then dispatch an action with those loaded products.

function loadProducts() {
  // Return a thunk
  return function(dispatch) {
    fetch('some-product-api-url')
      .then(res => res.json())
      .then(data => {
        dispatch({
          type: 'ADD_PRODUCTS',
          payload: data.products,
        });
      });
  };
}

And there we have it: A more practical application of the thunk concept!


References:

  1. Wikipedia: Thunk
  2. redux-thunk

Nick Scialli is a software engineer at the U.S. Digital Service.