Home > Software engineering >  Recursive function still being called even when the condition for the while loop is not met
Recursive function still being called even when the condition for the while loop is not met

Time:06-12

I am tying to write a recursive function that would keep on fetching some paginated data from an api until it fetches all the data from all the pages.

For example the data from the api return this {"pageCount": 3, "pageNumber": 1} so I want to recursively call the api each time by incrementing the page number until it reaches 3 and then it stops. The issue that I am facing is that the recursive function is being called an additional time even though the condition for the while loop is not met. Here is my code:

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);

This is the output that I am getting:

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

CodePudding user response:

The while loop isn't necessary here for a recursive solution, simply return the function with the page incremented by one. You have defined a base case if (page === pagecount) which is good, but you need to stop the recursion with a return statement at some point. I removed the while loop and updated your code.

You can choose to modify the return results as you see fit, that is whether you want to return nothing or return some meaningful data when the recursion encounters the base case.

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);

CodePudding user response:

Two main things to note here:

  1. You are not returning the function somewhere in between, which means that whenever the function is called it will get executed completely from the start to the bottom.
  2. Whenever you call a function and pass it some arguments, those arguments are scoped inside that function, which means every function call to testfunc(page) has its own copy of the page variable.

The reason why you get the last output two times is hard to explain but we can visualize it if we trace the whole flow:

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
}

Hope the above code explains why we get the last output two times!

  • Related