I’m trying to access an API to pull stock data. The free plan only lets me make 5 calls per minute. I’m trying to use native JS/jQuery to make the calls. Using some example code I’ll illustrate my issue (using 3 second intervals). I initially thought that putting setTimeout()
within a for-loop that prints to the console would print, wait 3 seconds, print, wait 3 seconds, repeat… But what it does is wait 3 seconds, and then prints all the lines at once. I understand this now. It seems bad practice to "lock up" execution of a program, but I’m starting to think that is what needs to be done here?
$(function() {
for (var i = 0; i < 5; i++) {
doSetTimeout(i);
}
});
function doSetTimeout(i) {
setTimeout(function() { console.log(i); }, 3000);
}
I also tried "locking up" the program with a while-loop and time delay. But my entire browser just froze and became unresponsive for much longer than the time inputted.
function pauseExecution(miliseconds) {
var currentTime = new Date().getTime();
while (currentTime + miliseconds >= new Date().getTime()) {
}
}
2
Answers
As others have mentioned,
setTimeout
is async. What is happening is you are scheduling5
tasks to complete after roughly3000ms
. What you should do is not queue another task until the previous one has completed. This can be achieved in about a million way.Async/Await
If you can, just use
async/await
. Its the easiest with the least amount of code.Promise
Creating a promise chain where every task is dependent on a
delay
and aunit of work
would serve a similar purpose asasync/await
if you are not transpiling ect. You have to be careful withcatch
ect to make this production ready.Queues
This is probably the most complex solution. You create a
blocking queue
. All tasks can be queued whenever but the queue will only execute the next task after the current task callsnext
. This is not production ready and is meant to serve as an example. There are issues with stack overflows with sync operations as well as exception handling.SetInterval
If you dont need to block on previous operations(ajax/fetch) you could simply use a
setInterval
. This just schedules a task eveyN
ms regardless of the state of the previous tasks.Ohh I have already done something like that, What you need to do is run and wait for the func to end.
See this example to understand.