javascript || Angular2/6: Calling setInterval multiple times but last timerId is not stopping even though clearInterval called
Asked Answered
G

1

1

Requirement:

  1. User scans multiple job numbers, for each job number , I need to call one API and get the total job details and show it in a table below the scanned text box.

  2. User don't want to wait until API call finishes. He will scan continuously irrespective of details came or not.

What I have done:

  1. I have taken one variable jobNumberList which stores all the job numbers the user scanned
  2. I am continuously calling the API, with those job numbers.
  3. When API, gives response , then I am adding to the table
  4. I created one method called m1()
  5. m1() =>
    • this method will compare the jobNumberList with the Table Rows data.
    • if any item not found in the table rows data when compare to jobNumberList data, then those are still loading jobs ( means API , not given response to those jobs )
  6. I am using setInterval() to call m1() (time inteval = 1000 )
  7. When jobNumberList and the Table rows data matches then I am cancelling the interval

Issue: Even though I am stopping the polling, still the interval is executing. What will be the issue?

*

The issue is intermittent (not continuous). When I scan job numbers fast, then its coming. Normal speed not coming.

*

My Code is as follows

 // START INTERVAL  
 startPolling() {
    var self = this;
    this.isPollingNow = true;
    this.poller = setInterval(() => {
      let jobsWhichAreScannedButNotLoadedInsideTableStill = self.m1();
      if (self.isPollingNow && jobsWhichAreScannedButNotLoadedInsideTableStill.length === 0) {
        self.stopPolling();
        self.isPollingNow = false;
      }
    }, 1000);
  }

  //STOP INTERVAL
  stopPolling() {
    var self = this;
    setTimeout(function () {
      window.clearInterval(self.poller); // OR  //clearInterval(self.poller) //
    }, 0);
  }

REQUIREMENT

enter image description here

DEBUGGING IMAGES

My CODE

ZONE JS 1

ZONE JS3

Goldsmith answered 16/10, 2018 at 13:24 Comment(21)
my guess is you trigger startPolling more than once.Hutchens
I tried your code and when i call stopPolling the interval stops. So like @Hutchens said i think you're calling startPolling more than once.Kerns
Yes, for each job number scan I am calling startPolling and stopping when jobNumberList and the Table rows data matches.Goldsmith
Is this wrong? if yes, can you explain in detail why my architecture is wrong? and second what is the recommended way..Goldsmith
@Hutchens ,mika , suggest meGoldsmith
if (this.poller) { window.clearInterval(this.poller); } this.poller = setInterval(() => {Hutchens
you mean to say, 1st stop the timers if any and then start the polling?Goldsmith
@Hutchens I am displaying loading symbol, when jobs which are scanned is not equal to the table rows. When its equal stop the polling. I tried clearInterval, but the loading symbol not displaying now with your code.Goldsmith
how many poller you can have at the same time ? just one or would be more ?Grazia
@JohuderGonzalez I have added some images to show the requirement. pollid 36 and 55 is just for example. dont confuse among them. The concept I am showing. Each time when user scans a Job Number I am calling startPoll(for 1000ms). when jobs loaded inside table === scanned jobs , then I am calling stop polling.. if not equal then showing the loading symbol with leftout jobs (means still not loaded inside table, i,e, response not came from api)Goldsmith
@Hutchens I added some images, it may help in investigating the issue. ThanksGoldsmith
well you will get a different id every time you create a new timout.Hutchens
@Hutchens yes, but i am calling stopInterval when table rows count ===scanned count, so created timers will be cleared peridically, except the last timerid.. :(Goldsmith
but are you positive that startPolling() is not being called before the timer has been removed?Hutchens
@Hutchens I am calling stopPolling only when the data inside table is equal to the scanned data. Means , data inside table is from API responses for each scan. If api gives late response but user dont care and he keeps on scanning. Each time user scans a jobNumber barcode then startPolling() is executed. But stopPolling() will be called only when dataRows length inside table is equal to the scanning list. So, in this case startPolling() will be called multiple times before stopPolling calls. So I am not positive about startPolling() called before timer has been removed.Goldsmith
@JohuderGonzalez please check my comments.Goldsmith
That is my point, you overwrite the timeout everytime you call it. So once you do that, you overwrite the interval. Your code only works to have ONE timeout at a time. If you want to have multiple timeouts, you have to rethink how you are storing all the intervals to cancel them.Hutchens
Let us continue this discussion in chat.Goldsmith
@Hutchens , Hi Can you pls explain a bit more. I didnt understand the last pointGoldsmith
@Goldsmith your images are a little difficult to see it, so I recommend you create a kind of auto clear interval into a isolate function, I will do some code to illustrate what I am talking about.Grazia
@JohuderGonzalez Regarding the images, 1st image is my code and the next images are clearInterval function debugged inside javascript core (zone.js)Goldsmith
G
1

The following code will create and auto cancellable interval when there is not more jobs to scan, this principle will do the trick that you need, please ask if you have any doubt.

Use the Clear Jobs button to remove jobs into the array that keep all the existing jobs

var globalsJobs = [1,2,3,4];

function scannableJobs () {
	return globalsJobs;
}

function generateAutoCancellableInterval(scannableJobs, intervalTime) {
	var timer;
	var id = Date.now();
  
  timer = setInterval(() => {
  	console.log("interval with id [" + id + "] is executing");
    var thereUnresponseJobs = scannableJobs();
    if (thereUnresponseJobs.length === 0) {
    	clearInterval(timer);
    }
  }, intervalTime)
}

const btn = document.getElementById('removejobs');
const infobox = document.getElementById('infobox');
infobox.innerHTML = globalsJobs.length + ' jobs remainings'

btn.addEventListener('click', function() {
	globalsJobs.pop();
  infobox.innerHTML = globalsJobs.length + ' jobs remainings'
}, false);

setTimeout(() => generateAutoCancellableInterval(scannableJobs, 1000), 0);
setTimeout(() => generateAutoCancellableInterval(scannableJobs, 1000), 10);
<button id="removejobs">
  clear jobs
</button>

<div id="infobox">
  
</div>
</div>
Grazia answered 18/10, 2018 at 19:41 Comment(4)
why you added " && polling" . Once we call clearInterval(), then setInterval() function should not executed right...Goldsmith
It wont serve the purpose, I made a jsbin for my scenario , please have a look;jsbin.com/dihesat/edit?js,console (ADD JQUERY PLUGIN FROM ADD LIBRARY MENU)Goldsmith
The issue is, its calling continuously without stoppingGoldsmith
polling not stoppingGoldsmith

© 2022 - 2024 — McMap. All rights reserved.