Nick Scialli • January 31, 2020 • 🚀 3 minute read

If you're enjoying this blog, please consider one or both of the following:

“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 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: