find the time left in a setTimeout()? find the time left in a setTimeout()? javascript javascript

find the time left in a setTimeout()?


Just for the record, there is a way to get the time left in node.js:

var timeout = setTimeout(function() {}, 3600 * 1000);setInterval(function() {    console.log('Time left: '+getTimeLeft(timeout)+'s');}, 2000);function getTimeLeft(timeout) {    return Math.ceil((timeout._idleStart + timeout._idleTimeout - Date.now()) / 1000);}

Prints:

$ node test.js Time left: 3599sTime left: 3597sTime left: 3595sTime left: 3593s

This doesn't seem to work in firefox through, but since node.js is javascript, I thought this remark might be helpful for people looking for the node solution.


EDIT: I actually think I made an even better one: https://stackoverflow.com/a/36389263/2378102

I wrote this function and I use it a lot:

function timer(callback, delay) {    var id, started, remaining = delay, running    this.start = function() {        running = true        started = new Date()        id = setTimeout(callback, remaining)    }    this.pause = function() {        running = false        clearTimeout(id)        remaining -= new Date() - started    }    this.getTimeLeft = function() {        if (running) {            this.pause()            this.start()        }        return remaining    }    this.getStateRunning = function() {        return running    }    this.start()}

Make a timer:

a = new timer(function() {    // What ever}, 3000)

So if you want the time remaining just do:

a.getTimeLeft()


If you can't modify the library code, you'll need to redefine setTimeout to suit your purposes. Here's an example of what you could do:

(function () {var nativeSetTimeout = window.setTimeout;window.bindTimeout = function (listener, interval) {    function setTimeout(code, delay) {        var elapsed = 0,            h;        h = window.setInterval(function () {                elapsed += interval;                if (elapsed < delay) {                    listener(delay - elapsed);                } else {                    window.clearInterval(h);                }            }, interval);        return nativeSetTimeout(code, delay);    }    window.setTimeout = setTimeout;    setTimeout._native = nativeSetTimeout;};}());window.bindTimeout(function (t) {console.log(t + "ms remaining");}, 100);window.setTimeout(function () {console.log("All done.");}, 1000);

This is not production code, but it should put you on the right track. Note that you can only bind one listener per timeout. I haven't done extensive testing with this, but it works in Firebug.

A more robust solution would use the same technique of wrapping setTimeout, but instead use a map from the returned timeoutId to listeners to handle multiple listeners per timeout. You might also consider wrapping clearTimeout so you can detach your listener if the timeout is cleared.