Home > Software design >  Sort of await setInterval
Sort of await setInterval

Time:03-22

I need to re-execute a hand made for loop (because I need time between each step) 10s after it ends forever.

So after few tries, I came with this code, but it doesn't work because it re-executes every 10s, not after the loop finishes. I tried to but async function in the interval and put all my code in an await one, but it didn't work.

async function refreshEDT() {
    let rows = appModel.getAll()
    let orderFiliere = {};
    await rows.then((res) => {
        for (let i = 0; i < res.length; i  ) {
            if (res[i].filiere in orderFiliere) {
                orderFiliere[res[i].filiere].push(res[i])
            } else {
                orderFiliere[res[i].filiere] = [res[i]]
            }
        }
    })
    return orderFiliere
}

let edt = refreshEDT()
setInterval(() => {
    edt = refreshEDT()
}, 1000 * 60 * 60) //ms to s to m to h
setInterval(() => {
    edt.then((lessons) => {
        (function loop(i) {
            let lessons_key = Object.keys(lessons)
            setTimeout(() => {
                // processing things
                if (--i) loop(i);
            }, 1000 * 10) //ms to s to 10s
        })(Object.keys(lessons).length - 1)
    })
    console.log(1)
}, 1000 * 10) //ms to s to 10s

Do you have any solution?

Ty!

EDIT Let's explain what I try to do: I get things on my DB, try to classify by "filiere", one of my column, and return that object. Those data are reloaded every hour. After that, I need to emit with socket.io every "filiere" with 10s between, and repeat that.

CodePudding user response:

Perhaps the code will be easier to read when you wrap setTimeout with a promise to await.

function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function refreshEDT() {
  const res = await appModel.getAll();
  const orderFiliere = res.reduce((acc, value) => {
    const { filiere } = value;

    if (filiere in acc) {
      acc[filiere].push(value);
    } else {
      acc[filiere] = [value];
    }

    return acc;
  }, {});

  return orderFiliere;
}

// consider naming this
(async () => {
  let edt = refreshEDT();

  setInterval(() => {
    edt = refreshEDT();
  }, 1000 * 60 * 60);

  while (true) {
    const lessons = await edt;

    for (const lessons_key of Object.keys(lessons)) {
      await sleep(1000 * 10);
      // processing things
    }

    // repeat after 10 seconds
    await sleep(1000 * 10);
  }
})();

With ES2022, you can use Array.prototype.groupBy() to simplify your refreshEDT() implementation:

async function refreshEDT() {
  const res = await appModel.getAll();
  const orderFiliere = res.groupBy(({ filiere }) => filiere);

  return orderFiliere;
}

CodePudding user response:

You could try using setTimeout to call your function again.

const myFunc = () => {
    
    // processing things

    setTimeout(myFunc , 10000)
}
myFunc();

CodePudding user response:

I think this could help if i understood the problem correctly :

const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async yourFunction() {
  const secondsToWait: number = 10;
  let i = 0;
  for (let item of List) {
    // Do stuff
    
    if (i === list.length -1) {
      await wait(secondsToWait*1000);
      yourFunction();
    }
    i  ;
  }
}
  • Related