Using sleepTimeout in JavaScript
tldr: ALWAYS take a brief look at official developer documentation of functions.
I was trying to rush a release over weekend and I had requirement where I was to make repeated API calls to track progress of status of task. Without that any new user would be seeing a "dead page" without any info on what is going on and how he/she should proceed. Pseudo code would be something like:
function get_task_status(task_id) {
$.get("/get_task_status/", {'task_id':task_id})
.done( function(data) {
// Update status div
// Wait for x seconds and repeat this function
});
}
As usual I hurried to Google search the template/pointer code. StackOverflow didn't disappoint and I landed up with this discussion. It had decent insight on using callback function with setTimeout and I cooked up my own version of it:
function get_task_status(task_id) {
$.get("/get_task_status/", {'task_id':task_id})
.done( function(data) {
if(data['task'] === 'PROGRESS') {
Materialize.toast(data['info'], 1000);
setTimeout(get_task_status(task_id), 2000);
}
});
}
Looks innocent
right? Well that's what got me stumped for almost 3-4
hours. I tried this and my javascript happily ignored setTimeout and
delay in seconds and kept making continues GET requests. I tried some
variants of above code but nothing worked. Eventually I came across
this post on SO, tried the code and it worked! I was convinced that
there was some issue with older version handling of setTimeout and
2016 update
is what I needed.
Today as I sat to put together a brief note of this experience I was testing setTimeout code on node, browser console, inside HTML template and somehow each time delay was working just fine:
function get_task_status() {
console.log(Date());
setTimeout(get_task_status, 2000);
}
> function get_task_status(task_id) {
... console.log(Date());
... // Recursive call to this function itself after 2 seconds of delay
... setTimeout(get_task_status, 2000);
... }
undefined
> get_task_status('something');
Tue Oct 25 2016 15:55:59 GMT+0530 (IST)
undefined
> Tue Oct 25 2016 15:56:01 GMT+0530 (IST)
Tue Oct 25 2016 15:56:03 GMT+0530 (IST)
Tue Oct 25 2016 15:56:05 GMT+0530 (IST)
Tue Oct 25 2016 15:56:07 GMT+0530 (IST)
Tue Oct 25 2016 15:56:09 GMT+0530 (IST)
(To exit, press ^C again or type .exit)
Again, this bummed me, I thought I had "established" that setTimeout
was broken and promise
is what I should be looking at and get better
understanding of. While trying to work it out and understand what is
wrong as I checked MDN documentation of the function and I finally
realized my real bug. Syntax of function is
var timeoutID = window.setTimeout(func[, delay, param1, param2, ...]);
And this is what I was doing:
setTimeout(get_task_status(task_id), 2000);
Notice in syntax params are after the delay argument while I just used
them directly and this was the small gotcha
. I was talking to Syed
ji about this experience and he pointed to You don't know series for
better understanding of javascript concepts and nuances. I learned my
lesson, properly RTFM
and as for promise
, I will return to learn
more about it later, at the moment my code is working.