Journal Contact

Quick Tip: Recursively Calling a Function that Returns a Promise


Occasionally, you may find yourself writing a function that returns a Promise, but also might need to recursively call itself.

Let's look at a basic function call that returns a Promise.

this.fetchPaginatedData().then((res) => {
  console.log("All data fetched!")
})

So how might we write that function, assuming it needs to be able to call itself? My first instinct was something like this:

const fetchPaginatedData = (page = 1) => {
 const promise = new Promise((resolve, reject) => {
   if (page == totalPages) {
     resolve()
   } else {
     fetchPaginatedData((page + 1))
   }
 }) 
return promise
}

The problem here is we're using something called explicit construction, which is a Promise anti-pattern. Since resolve() can assimilate Promises, we can instead wrap our recursive call with it.

resolve(fetchPaginatedData((page + 1)))

From the spec:

The argument passed to the resolve function represents the eventual value of the deferred action and can be either the actual fulfillment value or another Promise object which will provide the value if it is fulfilled.

The key here being resolve() can accept a Promise, instead of a direct value. It simply assumes that Promise will eventually resolve a proper value.

comments powered by Disqus