Reputation: 133
I need any solution or alternative for my Server Sent Event web app. I saw people using setInterval for SSE and which is good, but I have a function that take some time to run completely. Here is a situation that causing my web app to not work perfectly.
Take this example for the root cause. setTimeout will only executed after 1 sec. And setInterval supposed to run that function and then wait for 1/10 sec and then repeat it.
setInterval( () => {
setTimeout( function () { console.log("ok")}, 1000)
}, 100)
But in just 1 sec setInterval is running that function 10 times.
ok
ok
ok
ok
ok
ok
....
....
This is the actual code. Even if I set some conditions, that function is still running 3 times. And if I set setInterval time to 10 sec then its works fine then.
Is there any alternative in javascript that I can implement for Server Sent Events.
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)
Upvotes: 1
Views: 920
Reputation: 2966
If I'm understanding correctly, you're having issues with a setInterval time that is shorter than the time it takes your query to resolve?
If so, you can recursively call a function inside itself with a setTimeout, and that will steady the interval between resolves.
//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();
In your code this might translate to
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();
though may require tweaking.
Upvotes: 1
Reputation: 568
setInterval and setTimeout are all async, which means non-blocking you below code, the setTimeout() will be called 10 times in 1st second, first timeout callback a.k.a function () { console.log("ok") will be called after 1000ms, then 1100ms for 2nd callback, and so forth
setInterval( () => {
setTimeout( function () { console.log("ok")}, 1000)
}, 100)
```
Upvotes: 0
Reputation: 483
In your example where you used setTimeOut inside setInterval, it is working absolutely as it should. setInterval runs 10 times in a second, i.e. it calls setTimeOut 10 time in 1 sec. Now these setTimeOut is in the stack and once they've had timeout of 1 sec they execute.
So at the pass of 1 second you'll see 10 console.log(). Which it does above.
Coming to your actual question, setTimeOut and setInterval isn't the way to do this. You'll have to use 'Promise' for that.
Upvotes: 0