I need to update an image in a <canvas>
10 times per second, with data coming from an HTTP request:
var i = 0;
setInterval(() => {
i += 1;
console.log("sending request", i);
fetch("/data") // this can sometimes take more than 100 ms
.then((r) => r.arrayBuffer())
.then((arr) => {
// update canvas with putImageData...
console.log("finished processing", i);
});
}, 100);
It works, but since the request sometimes takes more than 100ms, it gives results like:
sending request 1
sending request 2
sending request 3
finished processing 3
sending request 4
sending request 5
finished processing 5
sending request 6
sending request 7
sending request 8
Question:
Are the "not-finished-to-process" requests queued for later (then it will make everything even slower!), or are they just dropped? By the way, how can I modify my example in order to test if it’s the former or the latter (I haven’t been able to to a MCVE confirming the former or latter)?
Since it’s video, I need to drop frames if the server takes too long to respond, how would you do it?
PS: example Python server code that takes 150 ms to respond:
import bottle, time
app = bottle.Bottle()
@bottle.route('/')
def index():
return open("test.html", "r").read()
@bottle.route('/data')
def data():
time.sleep(0.150)
return b"0000"
bottle.run(port=80)
2
Answers
Your output is currently wrong, therefore I would extract the code in a
function
, so that you always know whichi
you are currently in.Take a look at the async keyword in JavaScript. This helps you to wait for a promise to resolve before making another request. (If you don’t want to wait just remove the
await
in thesetInterval
). ThesendRequest
function will always resolve after 100ms.I think you can make use of the AbortControl API which will help you in taking the latest api response. AbortController cancels the other APIs if multiple API hits are there and in that case, you will always be receiving the latest API response. This strategy is useful when you are polling the server in regular intervals. FETCH and Axios both provide access to AbortControler. Below I’m add a custom hook which I used in my project. I hope it will help you in understanding the concept.
It is built using Axios where I’m using ref as a reference to the previous call.