2

I have a piece of a function where I need to iterate the loop on 15sec interval. I have already tried with setInterval() with timer value 15000 miliseconds(15 sec) but that is not working at all. I cannot use setTimeout() as I have to repeat the whole iteration of code inside the block. The question may look like a duplicate of other questions in Stackoverflow but the references and the examples posted is not working for my scenario. Please advice for the code given below.

EDIT :: Rickard (clarification by OP from comment)
On each iteration, I first need to check a value from the database. If the db returned value matches with the condition the iteration will execute its value and delay for 15secs for next iteration followed by the same db check. If on any iteration the db check does not match then the loop will exit at once. That is what I tried to do in the piece of code

acTripSess =[{el:Jhon, isIdleActive:1},{el:Chris, isIdleActive:1}]

for (i = 0; i < acTripSess.length; i++) {
     acTripItem = acTripSess[i];
    //console.log(acTripItem);
    (function (i) {
       setInterval(function () {
          if (acTripItem.isIdleActive == 1) {
             title = 'fleet_' + acTripItem.el; msg = 'tripFor_'+i;                     
             console.log(msg + ' notification on ' + title);
            }
       }, 15000);
     })(i)
}
            

EDIT

I even tried the same on another way but the loop is skipping on the 2nd element.

acTripSess = [
{el: 'Jhon', isIdleActive: 1},
{el: 'Chris', isIdleActive: 1},
{el: 'Steve', isIdleActive: 1}
];


for (var key in acTripSess) {
var acTripItem = acTripSess[key];
  //console.log(acTripItem);
if (key == 0) {  
    topic = 'driver_' + acTripItem.el;
    msg = 'newBooking_' + key;
    console.log(msg+' published on '+topic);
  } 
  else {
    setTimeout(function(){
      topic = 'driver_' + acTripItem.el;
      msg = 'newBooking_' + key;
      console.log(msg + ' published on ' + topic);
    },1000)
    continue;
  }
}
Rickard Elimää
  • 7,107
  • 3
  • 14
  • 30
Pal_IT-Dev
  • 37
  • 12
  • You need to move the `var acTripItem = acTripSess[i];` inside that IIFE (and add the `var` to it). Same for `i`, `title` and `msg`, they should be local variables. – Bergi Oct 28 '20 at 10:08
  • 2
    What do you mean by 'I have to repat the whole iteration of code inside the block'? Can you explain exactly what you are trying to do and at what times you want each part of your code to execute? It looks like you are setting up an interval for each element and all of them will fire at the same time every 15 seconds in perpetuity.... – Jason Goemaat Oct 28 '20 at 10:09
  • @Jason Goemaat On each iteration first I need to check a value from the database. If the db returned value matches with the condition the iteration will execute its value and delay for 15secs for next iteration followed by the same db check. If on any iteration the db check does not match then the loop will exit at once. That is what I tried to do in the piece of code. – Pal_IT-Dev Oct 28 '20 at 10:51

2 Answers2

1

You can use Promise and async function and await. And just loop it again after it's done

acTripSess = [{el: 'Jhon', isIdleActive: 1}, {el: 'Chris', isIdleActive: 1}]
var looper = async function () {
    for (i = 0; i < acTripSess.length; i++) {
        let acTripItem = acTripSess[i];
        await new Promise(function (resolve, reject) {
            setTimeout(function () {
                if (acTripItem.isIdleActive == 1) {
                    let title = 'fleet_' + acTripItem.el;
                    let msg = 'tripFor_' + i;
                    console.log(msg + ' notification on ' + title);
                }
                resolve(true);
            }, 1000);
        });
    }
    looper();//this will do it forever
};
looper();

I have modified this answer to meet you specifications

Updated: You don't really need to wait in the loop

acTripSess = [{el: 'Jhon', isIdleActive: 1}, {el: 'Chris', isIdleActive: 1}];
var check = function () {
    for (i = 0; i < acTripSess.length; i++) {
        acTripItem = acTripSess[i];
        if (acTripItem.isIdleActive == 1) {
            title = 'fleet_' + acTripItem.el;
            msg = 'tripFor_' + i;
            console.log(msg + ' notification on ' + title);
        }

    }
}

setInterval(check, 1000);//changed 15000 to 1000 for testing purposes
check();//don't wait 15 sec for initial check

//simulate change
setTimeout(function () {
    acTripSess = [{el: 'Jhon', isIdleActive: 1}, {el: 'Chris', isIdleActive: 0}, {el: 'NEW DATA', isIdleActive: 1}];
    console.log("data changed");
}, 2500);
angel.bonev
  • 2,154
  • 3
  • 20
  • 30
  • Thanks for the reply. But the problem is I need check a value from database in the beginning for each of the iteration. So I avoided the `setTimeout` in my code as the function will not go through the database check at the beginning of each iteration after delay. Please suggest – Pal_IT-Dev Oct 28 '20 at 10:39
  • @Pal_IT-Dev so you need to check all data every 15 seconds? – angel.bonev Oct 28 '20 at 11:19
  • Yes, that is what I really need in my code. – Pal_IT-Dev Oct 28 '20 at 11:35
  • @Pal_IT-Dev if i get it right you don't really need to wait in the loop just use setInterval and loop all data. I've updated my answer – angel.bonev Oct 28 '20 at 12:02
  • Thanks for your hard work. But for this scenario I am bound delay the loop else the purpose of this function will not resolve. Even I tried some other way, but the on the code the loop is skipping on the 2nd element of the array. – Pal_IT-Dev Oct 28 '20 at 15:51
0

You can do it like this:

let seconds = 15;
let waitTime = new Date(new Date().getTime() + seconds * 1000);
while(waitTime > new Date()){
    //do nothing here
}
//place your code waiting for execution here

It is a very bad practice because it blocks the main node thread but since you do not want(or can not) use setTimeout it gets the job done.

bamovh
  • 54
  • 5