setInterval 的替代方案,仅在函数执行时重复间隔

Alternative of setInterval for repeating interval only when function get executed

我的服务器发送事件网络应用程序需要任何解决方案或替代方案。我看到有人为 SSE 使用 setInterval,这很好,但我有一个功能需要一些时间才能完全 运行。这是导致我的网络应用无法正常运行的情况。

以这个例子为根本原因。 setTimeout 只会在 1 秒后执行。 setInterval 应该 运行 该函数然后等待 1/10 秒然后重复它。

setInterval( () => {
    setTimeout( function () { console.log("ok")}, 1000)
}, 100)

但在短短 1 秒内,setInterval 运行使该功能运行了 10 次。

ok
ok
ok
ok
ok
ok
....
....

这是实际代码。 即使我设置了一些条件,那个函数仍然是 运行ning 3 次。 如果我将 setInterval 时间设置为 10 秒,那么它就可以正常工作了。

javascript 中是否有我可以为服务器发送的事件实施的任何替代方案。

setInterval( () => {
        if ( pu[id] > 0 && pu[id]) {
            connection.query(`SELECT * FROM files WHERE pack_id = ${id} ORDER BY uploaded_at DESC LIMIT ${pu[id]}`, (error, results) => {
                if (error) {
                    console.log(error)
                } else {
                    console.log("SEND") // printing 3 times
                    res.status(200).write(`data: ${JSON.stringify(results)}\n\n`)
                }
                pu[id] = 0
            })
        }
    }, 10)

如果我没理解错的话,您遇到的问题是 setInterval 时间比解决查询所需的时间短?

如果是这样,您可以使用 setTimeout 递归调用自身内部的函数,这将稳定解析之间的间隔。

//query takes 1 second to resolve
function mockQuery () {
  return new Promise((resolve, reject)=> {
  setTimeout(()=> resolve(console.log("ok")),1000);
});
}

async function makeQueryCall(){
  await mockQuery()
  //after resolve it is called again 1/10th of a second later
  setTimeout(()=> makeQueryCall(), 100);
}

makeQueryCall(); 

在您的代码中,这可能会转化为

async function makeQueryCall() {
  if(pu[id] > 0 && pu[id]) {
      try {
          let results = await connection.query(`SELECT * FROM files WHERE pack_id = ${id} ORDER BY uploaded_at DESC LIMIT ${pu[id]}`); 
          console.log("SEND") // printing 3 times
          res.status(200).write(`data: ${JSON.stringify(results)}\n\n`)     
      } catch (e) {
          console.log(e)
      }
      setTimeout(()=> makeQueryCall(),10)
  }
}

makeQueryCall();

虽然可能需要调整。

在您的示例中,您在 setInterval 中使用了 setTimeOut,它完全可以正常工作。 setInterval 每秒运行 10 次,即它在 1 秒内调用 setTimeOut 10 次。 现在这些 setTimeOut 在堆栈中,一旦超时 1 秒,它们就会执行。

因此在 1 秒后您将看到 10 console.log()。它在上面做了什么。

关于您的实际问题,setTimeOut 和 setInterval 不是执行此操作的方法。为此,您必须使用 'Promise'。

setInterval和setTimeout都是async,也就是非阻塞 你在下面的代码中,setTimeout() 将在第一秒内被调用 10 次,第一次超时回调 a.k.a 函数 () { console.log("ok") 将在 1000 毫秒后调用,然后 1100 毫秒进行第二次回调, 等等

setInterval( () => {
    setTimeout( function () { console.log("ok")}, 1000)
}, 100)
```