Search code examples
javascriptsetintervalpolling

Calling setInterval multiple times then Clearing interval , polling not stopped


As my loop is so fast, the intervals are overlapping and not able to stop one timerId. here is my code:

data = ['115536', '117202']; // BARCODES AVAILABLE ON A4 SHEET //

var scan_delay = 500; // USER AVG SCANNING SPEED PER BARCODE //
var timerId;

var scannedItemsList = []; // ITEMS WHICH ARE SCANNED BY SEEING A4 SHEET BY THE USER //
var tableDataList = []; // TO SHOW DATA WHICH WE GOT FROM API //

Jbin

try {
var data = ['115536', '117202']; // BARCODES AVAILABLE ON A4 SHEET //

var scan_delay = 500; // USER AVG SCANNING SPEED PER BARCODE //
var timerId;

var scannedItemsList = []; // ITEMS WHICH ARE SCANNED BY SEEING A4 SHEET BY THE USER //
var tableDataList = []; // TO SHOW DATA WHICH WE GOT FROM API //



execute(data);

function execute(data) {
    var i = 0;
    scanSimulatorWithADelay(data, i);
}

function scanSimulatorWithADelay(data, i) {
    setTimeout(function () {
        getJobDetailsByCallingAPI(data[i], i);
        i++;

        if (data.length > i) {
            scanSimulatorWithADelay(data, i);
        } else {
            i = 0;
        }
    }, scan_delay);
}

function getJobDetailsByCallingAPI(jobNumber, index) {

    scannedItemsList.push(jobNumber);

    //poll_for_jobs_count_which_are_scanned_but_waiting_to_add_to_table
    startPolling();

    //Simulate API to get response after every 3 seconds//
    var apiDelay = (index + 1) * 3000;
    setTimeout(function () {
        console.log('API CALLED AT ' + new Date().toLocaleTimeString());
        CallTheAPI(jobNumber);
    }, apiDelay);

}

function CallTheAPI(jobNumber) {
    console.log("JOB NO " + jobNumber + " API response Recd");
    tableDataList.push(jobNumber);

}

function startPolling() {
    var pollStatus = '';
    timerId = setInterval(() => {
        debugger;
        console.log('timerId when starting interval ' + timerId);
        var jobsWhichAreScannedButNotLoaded = jobsWhichAreScannedButNotLoadedStill();
        console.log("$$$$$$ jobsWhichAreScannedButNotLoaded = " + jobsWhichAreScannedButNotLoaded.length);
        if (jobsWhichAreScannedButNotLoaded.length === 0) {
            console.log("@@@ Inteval Cleared @@@ " + timerId);

            //CLEAR TIMER
            clearInterval(timerId);

        } else {
            pollStatus = 'Polling inprogress and the pollID ' + timerId;
        }
        console.log('####' + pollStatus);
    }, 2000);

}

function jobsWhichAreScannedButNotLoadedStill() {
    let stillLoadingJobs = [];

    scannedItemsList.forEach(scannedItemsListJobNumber => {
        let foundJobInsideTable = false;
        if (scannedItemsListJobNumber) {
            foundJobInsideTable = tableDataList.indexOf(scannedItemsListJobNumber) > -1;
            if (!foundJobInsideTable) {
                stillLoadingJobs.push(scannedItemsListJobNumber);
            }
        }

    }); // End of scannedItemsList forEach loop 

    if (stillLoadingJobs.length > 0) {
        return stillLoadingJobs;
    }

    return [];
}
} catch (error) { throw error; }


Solution

  • Your timer_id variable is on the global scope and hence overwritten every time you call startPolling.

    So when you'll call clearInterval(timer_id), timer_id will be the id of the last setInterval, and the first one will keep running endlessly.

    Simply add a var in your startPolling function so that timer_id be scoped correctly, and that it doesn't get overwritten by next call.

    try {var data = ['115536', '117202'];
    
    var scan_delay = 500;
    // remove this one
    //var timerId;
    
    var scannedItemsList = [];  
    var tableDataList = []; 
    
    
    
    execute(data);
    
    function execute(data) {
      var i = 0;
      scanSimulatorWithADelay(data, i);
    }
    
    function scanSimulatorWithADelay(data, i) {
      setTimeout(function () {
        getJobDetailsByCallingAPI(data[i], i);
        i++;
    
        if (data.length > i) {
          scanSimulatorWithADelay(data, i);
        } else {
          i = 0;
        }
      }, scan_delay);
    }
    
    function getJobDetailsByCallingAPI(jobNumber, index) {
    
      scannedItemsList.push(jobNumber);
    
      //poll_for_jobs_count_which_are_scanned_but_waiting_to_add_to_table
      startPolling();
    
      //Simulate API to get response after every 3 seconds//
      var apiDelay = (index + 1) * 3000;
      setTimeout(function () {
        console.log('API CALLED AT ' + new Date().toLocaleTimeString());
        CallTheAPI(jobNumber);
      }, apiDelay) ;
    
    }
    
    function CallTheAPI(jobNumber) {
      $.ajax({
        url: "https://jsonplaceholder.typicode.com/todos/1",
        type: "GET",
        async: true,
        success: function (response) {
          console.log("JOB NO " + jobNumber + " API response Recd");
                        tableDataList.push(jobNumber);
        }
      });
    
    }
    
    function startPolling() {
      var pollStatus = '';
    /////////
    ///HERE
    /////////
    // Declare timerId in startPolling scope
    /////////
      var timerId = setInterval(() => {
        debugger;
        console.log('timerId when starting interval '+ timerId);
        var jobsWhichAreScannedButNotLoaded = jobsWhichAreScannedButNotLoadedStill();
        console.log("$$$$$$ jobsWhichAreScannedButNotLoaded = "+ jobsWhichAreScannedButNotLoaded.length);
        if (jobsWhichAreScannedButNotLoaded.length === 0) {
          console.log("@@@ Inteval Cleared @@@ "+ timerId);
    
          //CLEAR TIMER
          clearInterval(timerId);
          
        } else {
          pollStatus = 'Polling inprogress and the pollID ' + timerId;
        }
        console.log('####' + pollStatus);
      }, 2000);
    
    }
    
    function jobsWhichAreScannedButNotLoadedStill() {
      let stillLoadingJobs = [];
    
      scannedItemsList.forEach(scannedItemsListJobNumber => {
        let foundJobInsideTable = false;
        if (scannedItemsListJobNumber) {
          foundJobInsideTable = tableDataList.indexOf(scannedItemsListJobNumber) > -1;
          if (!foundJobInsideTable) {
            stillLoadingJobs.push(scannedItemsListJobNumber);
          }
        }
    
      }); // End of scannedItemsList forEach loop 
    
      if (stillLoadingJobs.length > 0) {
        return stillLoadingJobs;
      }
    
      return [];
    }
    } catch (error) { throw error; }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>