With a typical pagination API that returns
return fetch(url).then(result => result.nextPageHref
? fetchPaginated(result.nextPageHref).then(results => _.concat(result, results))
AFAIK the only way to do it without recursion is a native support to async-await and use a for loop. Note that compiled async-await will compile to some disguised recursive code too.
But this recursion is not recursion, as the call to
fetchPaginated is called from a callback, so the sync call stack will always be emptied before the callback (And thus it is little to do with tail recursion). If you are concerned about the browsers async call stack (which is there for debugging purposes only, we don't need async call stack to run a program), I think there should be a checkbox somewhere in the browsers developer tools to turn it off.