获取与setTimeout或setInterval相关的函数

4

假设我从setTimeoutsetInterval中获取了超时ID。

有没有一种方法可以获取与其关联的原始函数或代码?

类似这样:

var timer_id = setTimeout(function() {
    console.log('Hello Stackoverflowers!');
}, 100000);

var fn = timer_id.get_function(); // desired method
fn(); // output: 'Hello Stackoverflowers!'

3
据我所知,你需要自己编写一个 setTimeout 的包装器来实现该功能。 - Felix Kling
4个回答

4

您可以使用包装器setTimeout - 我只是在测试了几次之后才想到的这个方法...

(function() {
     var cache = {};

     var _setTimeout = window.setTimeout;
     var _clearTimeout = window.clearTimeout;

     window.setTimeout = function(fn, delay) {
         var id = _setTimeout(function() {
             delete cache[id];  // ensure the map is cleared up on completion
             fn();
         }, delay);
         cache[id] = fn;
         return id;
     }

     window.clearTimeout = function(id) {
         delete cache[id];
         _clearTimeout(id);
     }

     window.getTimeout = function(id) {
         return cache[id];
     }
})();

注意:如果您为回调使用字符串,则此方法将无法正常工作。但是,似乎没有人这样做,对吧?

此外,它不支持将ES5的附加参数传递给回调函数,尽管很容易实现该功能。


2
var timeouts = {};  // hold the data
function makeTimeout (func, interval) {

    var run = function(){
        timeouts[id] = undefined;
        func();
    }

    var id = window.setTimeout(run, interval);
    timeouts[id] = func;

    return id;
}
function removeTimeout (id) {
    window.clearTimeout(id);
    timeouts[id]=undefined;
}
function doTimeoutEarly (id) {
  func = timeouts[id];
  removeTimeout(id);
  func();
}

var theId = makeTimeout( function(){ alert("here"); }, 10000);
console.log((timeouts[theId] || "").toString());
timeouts[theId](); // run function immediately, will still run with timer

1
你可以将每个超时函数存储在一个对象中,以便稍后检索它。
var timeout_funcs = {};

function addTimeout(func,time) {
    var id = window.setTimeout(func,time);
    timeout_funcs[id] = func;
    return id;
}

function getTimeout(id) {
    if(timeout_funcs[id])
        return timeout_funcs[id];
    else
        return null;
}

function delTimeout(id) {
    if(timeout_funcs[id]) {
        window.clearTimeout(timeout_funcs[id]);
        delete timeout_funcs[id];
    }
}

1
这应该使用一个“对象”来保存它的数据,而不是一个数组。 - Alnitak
1
没有清理吗? - rogerdpack
编辑:添加了清理并从数组更改为对象。 - nicolas

0

setTimeout/setInterval返回的ID只是数字,除了每个数字都具有的属性和方法之外,它们没有其他属性或方法。如果想获取该函数,可以先声明它,而不是使用匿名方式:

var myFunc = function() {
    console.log('Hello Stackoverflowers!');
};

var timer_id = setTimeout(myFunc, 100000);

myFunc(); // output: 'Hello Stackoverflowers!'

clearTimeout(timer_id); // unless you want it to fire twice

OP说他们有ID,想要获取那个setTimeout ID所关联的函数。你的回答并没有解决这个问题。 - epascarello
@epascarello 因为这是不可能的,ID只是一个数字。 - jbabey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接