Estoy tratando de escribir una función recursiva que siga obteniendo algunos datos paginados de una API hasta que obtenga todos los datos de todas las páginas.
Por ejemplo, los datos de la API devuelven este {"pageCount": 3, "pageNumber": 1} , por lo que quiero llamar recursivamente a la API cada vez incrementando el número de página hasta que llegue a 3 y luego se detenga. El problema al que me enfrento es que la función recursiva se llama una vez más, aunque no se cumple la condición para el bucle while. Aquí está mi código:
let pagecount = 3; let i = 1; const testfunc = (page) => { console.log("apicalled with page", page); console.log("page", page, "pagecount", pagecount); if (page === pagecount) { console.log("condition fulfilled", page !== pagecount); } while (page !== pagecount) { page++; testfunc(page); } }; testfunc(i);Esta es la salida que estoy obteniendo:
apicalled with page 1 page 1 pagecount 3 apicalled with page 2 page 2 pagecount 3 apicalled with page 3 page 3 pagecount 3 condition fulfilled false //Should stop here apicalled with page 3 page 3 pagecount 3 condition fulfilled false
Dos cosas principales a tener en cuenta aquí:
testfunc(page) tiene su propia copia de la variable de page .La razón por la que obtienes la última salida dos veces es difícil de explicar, pero podemos visualizarla si rastreamos todo el flujo:
testfunc(1) { // let name this function scope as A // console.log -> apicalled with page 1 // console.log -> page 1 pagecount 3 while(1 != 3) { // page value is 1 here in scope A page++ // page value become 2 here in scope A, testfunc(2) { // let name this function scope as B // console.log -> apicalled with page 2 // console.log -> page 2 pagecount 3 while(2 != 3) { // page value is 2 here in scope B page++ // page value becomes 3 here in scope B, testfunc(3) { // let name this function scope as C // console.log -> apicalled with page 3 // console.log -> page 3 pagecount 3 // console.log -> condition fulfilled false while(3 != 3) { // page value is 3 here in scope C // condition is false so loop doesn't executes } // <- function execution completed } } while(3 != 3) { // page value is 3 here in scope B // condition is false so loop doesn't executes } // <- function execution completed } } while(2 != 3) { // page value is 2 here in scope A page++ // page value becomes 3 here in scope A, testfunc(3) { { // let name this function scope as D // console.log -> apicalled with page 3 // console.log -> page 3 pagecount 3 // console.log -> condition fulfilled false while(3 != 3) { // page value is 3 here in scope D // condition is false so loop doesn't executes } // <- function execution completed } } while(3 != 3) { // page value is 3 here in scope A // condition is false so loop doesn't executes } // <- function execution completed }¡Espero que el flujo de código anterior explique por qué obtenemos el último resultado dos veces!
El bucle while no es necesario aquí para una solución recursiva, simplemente devuelve la función con la página incrementada en uno. Ha definido un caso base if (page === pagecount) que es bueno, pero necesita detener la recursividad con una declaración de devolución en algún momento. Eliminé el bucle while y actualicé tu código.
Puede optar por modificar los resultados devueltos como mejor le parezca, es decir, si no desea devolver nada o devolver algunos datos significativos cuando la recursividad encuentra el caso base.
let pagecount = 3; let i = 1; const testfunc = (page) => { console.log("apicalled with page", page); console.log("page", page, "pagecount", pagecount); // this is the recursion base case if (page === pagecount) { console.log("condition fulfilled", page !== pagecount); return } return testfunc(page+1) } testfunc(i);