有点等待 setInterval

Sort of await setInterval

我需要在它永远结束后 10 秒重新执行一个手工制作的 for 循环(因为我需要在每个步骤之间留出时间)。

所以经过几次尝试,我得到了这段代码,但它不起作用,因为它每 10 秒重新执行一次,而不是在循环完成后。我尝试在间隔中使用 async 函数并将我的所有代码放入 await 中,但它没有用。

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

你有什么解决办法吗?

太棒了!

编辑 让我们解释一下我尝试做的事情: 我在我的数据库中获取内容,尝试按“filiere”(我的专栏之一)和 return 该对象进行分类。 这些数据每小时重新加载一次。 之后,我需要用 socket.io 发出每个“filiere”,中间间隔 10 秒,然后重复。

您可以尝试使用 setTimeout 再次调用您的函数。

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

    setTimeout(myFunc , 10000)
}
myFunc();

也许当您用对 await 的承诺包装 setTimeout 时,代码会更容易阅读。

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);
  }
})();

使用 ES2022,您可以使用 Array.prototype.groupBy() 来简化您的 refreshEDT() 实现:

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

  return orderFiliere;
}

如果我正确理解问题,我认为这会有所帮助:

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++;
  }
}