Home > Back-end >  Nodejs setInterval and run first immediatly not after interval
Nodejs setInterval and run first immediatly not after interval

Time:07-18

I try to implement a loop in my noejs app that will always wait between the tasks. For this I found the setInterval function and I thought it is the solution for me. But as I found out, the first Interval, means the very first action also wait until the interval is ready. But I want that the first action runs immediatly and then each action with the given interval. In arry scope: myArray[0] starts immediatly while myArray[1..10] will start with Interval waiting time.

I tried it with:

function rollDice(profilearray, browserarray, url) {
  return new Promise((resolve, reject) => {
    var i = 0;
    const intervalId = setInterval(
      (function exampleFunction() {
        console.log(profilearray[i].profil);
        //########################################################################

        createTestCafe("localhost", 1337, 1338, void 0, true)
          .then((tc) => {
            testcafe = tc;
            runner = testcafe.createRunner();
            inputStore.metaUrl = url;
            inputStore.metaLogin = teamdataarray[0].email;
            inputStore.metaPassword = teamdataarray[0].password;
            inputStore.moderator = profilearray[i].profil;
            inputStore.message = profilearray[i].template;
            inputStore.channelid = profilearray[i].channelid;
          })
          .then(() => {
            return runner
              .src([__basedir   "/tests/temp.js"])
              .browsers(browserarray)
              .screenshots("", false)
              .run()
              .then((failedCount) => {
                testcafe.close();

                if (failedCount > 0) {
                  console.log(profilearray[i].profil);
                  console.log("No Success. Fails: "   failedCount);
                  //clearInterval(intervalId);
                  //reject("Error");
                } else {
                  console.log(profilearray[i].profil);
                  console.log("All success");
                  //clearInterval(intervalId);
                  //resolve("Fertig");
                }
              });
          })
          .catch((error) => {
            testcafe.close();
            console.log(profilearray[i].profil);
            console.log("Testcafe Error"   error);
            //clearInterval(intervalId);
            //reject("Error");
          });

        //######################################################################

        i  ;
        console.log("Counter "   i);
        if (i === profilearray.length) {
          clearInterval(intervalId);
          resolve("Fertig");
        }
        return exampleFunction;
      })(),
      3000
    ); //15 * 60 * 1000 max time to wait (user input)
  });
}

The way I have done works bad because in the first action it will not start the testcafe. But in all other actions it will do. Anybody knows a better way to do this?

Scope: Give a array of data and for each array start testcafe with a given waiting time. 3 seconds up to 15 minutes. Because in some cases 15 Minutes is a long time I want to start the first one without any waiting time. Iam open for any suggestion

CodePudding user response:

Declare function before setInterval, run setInterval(exampleFunction, time) and then run the function as usual (exampleFunction()). May not be ideal to the millisecond, but if you don't need to be perfectly precise, should work fine.

Ask if you need further assistance

EDIT: now looking twice at it, why are you calling the function you pass as parameter to setInterval inside the setInterval?

CodePudding user response:

For modern JavaScript await and async should be used instead of then and catch.

This will make many things easier, and the code becomes more readable. You e.g. can use a regular for loop to iterate over an array while executing asynchronous tasks within it. And use try-catch blocks in the same way as you would in synchronous code.

// a helperfunction that creates a Promise that resolves after
// x milliseconds
function wait(milliseconds) {
   return new Promise(resolve => setTimeout(resolve, milliseconds))
}

async function rollDice(profilearray, browserarray, url) {
  for (let i = 0; i < profilearray.length; i  ) { 
    // depending how you want to handle the wait you would create
    // the "wait"-Promise here
    // let timer = wait(3000)

    let testcafe = await createTestCafe("localhost", 1337, 1338, void 0, true);
    
    try {
      let runner = testcafe.createRunner();
      inputStore.metaUrl = url;
      inputStore.metaLogin = teamdataarray[0].email;
      inputStore.metaPassword = teamdataarray[0].password;
      inputStore.moderator = profilearray[i].profil;
      inputStore.message = profilearray[i].template;
      inputStore.channelid = profilearray[i].channelid;

      let failedCount = await runner.src([__basedir   "/tests/temp.js"])
        .browsers(browserarray)
        .screenshots("", false)
        .run()

      if (failedCount > 0) {
        // ...
      } else {
        // ...
      }
    } catch (err) {
      console.log(profilearray[i].profil);
      console.log("Testcafe Error"   error);
    } finally {
      testcafe.close();
    }

    // Here you would wait for the "wait"-Promise to resolve:
    // await timer;
    // This would have similar behavior to an interval.

    // Or you wait here for a certain amount of time.
    // The difference is whether you want that the time the 
    // runner requires to run counts to the waiting time or not.
    await wait(3000)
  }

  return "Fertig"
}
  • Related