0

This is more of a question on how I should approach my problem, and not what code to use. this is the general framework/simplification of my code. I can provide the actual code if needed. question is below, it is similar to the last question I asked as it is part of the same system that isn't working:


for (i = 0; i < 10; i++) {
  var amt = 0;

  function checktime() {
    console.log(amt + " / " + i);
    amt++;

    if (amt <= 5) {
      setTimeout(checktime, 3000);
    }
  }

  checktime();
}

I want it to have all the set timeouts running at once, for each i. the console results in 0 / 0

0 / 1

0 / 2

...

0 / 8

0 / 9

1 / 10

2 / 10

3 / 10

4 / 10

...

13 / 10

14 / 10

I'd like it to look like this:

0/0

0/1

0/2

0/3

...

0/9

1/0

1/1

...

5/9

5/10

sorry for the long question, but how would I go about doing this?

Ranjul Arumadi
  • 109
  • 1
  • 2
  • 11
Huddy
  • 15
  • 7
  • OK first of all, it's not a good idea to define a function inside the for loop like this. Let's first try to have the function `checktime` be outside the loop, and give it a parameter like : `function checktime(amt) { //do stuff with amt }`, this way you can easily follow what's happening to amt, plus I don't see a case where `amt` is ever increased since at the start of the loop you keep setting it to `var amt = 0;` – SaleemKhair Jul 30 '21 at 01:19
  • thats just to make sure each set timeout runs 5 times. i increase it in checktime() – Huddy Jul 30 '21 at 01:21

2 Answers2

2

Have a function inside checktime that runs a loop. Set up your variables, and then pass the count variable into the inner function again with your setTimout.

function checktime() {

  // Set the amt variable to zero
  let amt = 0;

  // Set count to zero if it doesn't exist
  function loop(count = 0) {

    // Log the new data
    console.log(`${amt}/${count}`);

    // Increase the count
    ++count;

    // If count hits 10 reset the count
    // and increase the amt variable
    if (count === 10) {
      count = 0;
      ++amt;
    }

    // Call the loop function again and pass in the new count
    // as a parameter
    setTimeout(loop, 1000, count);

  }

  loop();

}

checktime();
Andy
  • 61,948
  • 13
  • 68
  • 95
  • that looks good, thanks, just two further questions that pertain more to the specifics of my code. one, where would i put something that waits for a certain amt of ms before starting the loop, and also, how would I loop the loop every hour or so? – Huddy Jul 30 '21 at 01:44
  • You could use `setTimeout` on the main function like `setTimeout(checktime, 5000);` As for the other part unless your browser has been open for than long you can't. You'd have to keep a log of when the last time the function was run in something like localStorage, and then have the code check that when the site reloads, and then rerun the function. – Andy Jul 30 '21 at 01:47
  • this is running in a background script on a chrome extension, so as long as chrome is running it will be able to run. I'm just wondering where to put it so it doesn't interrupt the flow of the code ig – Huddy Jul 30 '21 at 01:50
  • It shouldn't. JS is single-threaded and things like event listeners, and async processes, and setTimeouts are shoved out to an new stack and then reintroduced to the main thread when they're complete. Extensions are also sandboxed, so there should be no issue. I've written some very time-consuming extensions for FF and there have been no performance issues. – Andy Jul 30 '21 at 02:12
  • If you wanted to put your code on Github when you're done I'd be happy to look over it for you. – Andy Jul 30 '21 at 02:15
  • that'd be great, i dont use github, is there any other way I can get it to you? also, the code is very nested and kind of messy with a ton of different functions all kind of similar for the framework to the one I posted – Huddy Jul 30 '21 at 02:26
  • I'm having trouble implementing it in my actual code, do you think you can help me translate that approach to that part of my actual code? its a decently simple function. if not that's fine – Huddy Jul 31 '21 at 18:22
  • I'll try. Put your code in [pastebin](https://pastebin.com/) and I'll look it over. Just add some comments in the code to show me what you're trying to do, and to let me know what to look for. I can't make any promises though, ok? – Andy Jul 31 '21 at 18:24
  • that'd be great. i'll put it all in right now – Huddy Jul 31 '21 at 18:26
  • actually i can make some more changes myself then ill send it over – Huddy Jul 31 '21 at 18:46
  • I figured it out :D your approach helped. spent like 4 hours on it today – Huddy Aug 01 '21 at 00:10
  • Sometimes that's what it takes. :) I'm glad it helped. Good luck with the coding. – Andy Aug 01 '21 at 00:40
  • BTW [you may find this an interesting read](https://justjavascript.com/). – Andy Aug 01 '21 at 00:40
  • that was pretty interesting, thanks. not fully understanding the concept fully applies to me lol – Huddy Aug 02 '21 at 21:39
0

There are 2 ways you can do this.

  1. Using nested loops like this
for(i = 0; i< 10; i++){
        for(j = 0; j < 5; j++) {

                console.log(i + " / " + j)
                setTimeout(3000)
        }

}
  1. Using recursion like this:
function setTimeout_recurse(amt, i) {
        if (amt < 5) {
                console.log(i + " / " + amt)
                amt ++;
                setTimeout(3000)
                setTimeout_recurse(amt, i)
        }
}

for(i = 0; i< 10; i++){
        var amt = 0;
        setTimeout_recurse(amt, i);
}

You'll notice that the base is now i not amt which makes more sense to be the base.

SaleemKhair
  • 499
  • 3
  • 12
  • Yes this code will run in a single thread, no waiting involved here, but if you want to put some waiting functionality.. it can be implemented on the `_recurse` function.. what are you aiming to do eventually? – SaleemKhair Jul 30 '21 at 02:32
  • I want it to wait a certain amount of time to create a notification. i want that to repeat a certain amt of times per day or so – Huddy Jul 30 '21 at 02:35
  • lets say that your notification is this `console.log`, so do you want each log to wait 3 seconds before the next one, output would go like : `0 / 0 ~wait 3000~ 0 / 1....` or do you want it to push all 5 tries at once then wait? – SaleemKhair Jul 30 '21 at 03:01
  • Well you can do it 2 ways.. either using a single thread and accumulating the timeout duration... you can consider using `setInterval` instead of `setTimeout`... check out [this answer](https://stackoverflow.com/questions/7837830/javascript-setinterval-limits) – SaleemKhair Jul 31 '21 at 01:58