是否可以定义setTimeout函数返回ID值?

时间:2018-03-28 21:31:12

标签: javascript settimeout

Javascript setTimeout函数,创建一个内部ID,并在调用函数时返回该值。

我想要的是调用setTimeout,但是,指定setTimeout应该使用的内部ID,以后我可以使用我告诉的相同ID调用clearTimeout setTimeout要使用。

正常情况如下:

const id = setTimeout(function() {
    //Do stuff here
}, 1000);

//after a while...
clearTimeout(id);

我想要实现的案例:

const wantedId = 1234;
//Tell setTimeout somehow to use my wanted ID...
setTimeout(function() {
    //Do stuff here
}, 1000, wantedId);

//after a while...
clearTimeout(wantedId);

无论如何都要达到上述情况?

3 个答案:

答案 0 :(得分:1)

您可以覆盖功能setTimeoutclearTimeout

此方法返回一个对象,其中包含自定义ID和原始ID以停止情况

var originalSetTimeout = window.setTimeout;
var originalClearTimeout = window.clearTimeout;

window.clearTimeout = function(id) {
  if (id.originalId) {
    console.log('Clearing with custom id');
    originalClearTimeout(id.originalId)
  } else {
    originalClearTimeout(id);
  }
}

window.setTimeout = function() {
  var myId = 23232; //This is just to illustrate.
  return {customId: myId, originalId: originalSetTimeout.apply(null, arguments)};
}

const id = setTimeout(function() {
    console.log(id);
    clearTimeout(id);
}, 1000);

答案 1 :(得分:0)

您可以创建自己的包装类/函数,并保存与 setTimeout 返回的ID对应的ID的 hashmap 。例如:

class MyTimeout {
  constructor() {
    this.idMap = {};
  }

  setTimeout(myID, callback, time) {
    var originalID = window.setTimeout(callback, time);
    this.idMap[myID] = originalID;
    return myID;
  }

  clearTimeout(myID) {
    return window.clearTimeout(this.idMap[myID]);
  }
}


const t = new MyTimeout();
t.setTimeout('myID', () => { 
  console.log('fired!'); 
}, 2000);

t.clearTimeout('myID'); // Cancels the timeout
祝你好运!

答案 2 :(得分:0)

Ele的答案很好,但我认为可以改进。 如果要替换setTimeout,还应该替换clearTimeout,因为它们成对出现。 这需要您存储新的setTimeout函数创建的每个id,以便您可以在clearTimeout中恢复它。执行此操作的最佳方法是使用一个闭包来隐藏全局命名空间中的所有细节。

然后,您还可以在闭包内部使用一个恢复原始函数的函数。

下面的代码演示了所有这些。它会更改超时功能,然后创建3个超时。前两个证明它们是根据我们自己的id生成函数形成的。第三个演示了clearTimeout的工作原理。然后,程序创建一个新的超时,只是为了表明id不再遵循我们的模式,我们必须使用原始函数。

希望有所帮助。

var closure = function() {
    var originalSetTimeout = window.setTimeout;
    var originalClearTimeout = window.clearTimeout;
    idMap = {};
    var currentId = 1000;

    var nextId = function() {
        return currentId++;
    };

    window.setTimeout = function() {
        var returnedId = nextId();
        var localId = originalSetTimeout.apply(null, arguments);
        idMap[returnedId] = localId;
        return returnedId;
    };

    window.clearTimeout = function(idTimeout) {
        var localId = idMap[idTimeout];
        if (localId || localId === 0) {
            originalClearTimeout(localId);
            delete idMap[localId];
        }       
    };

    window.restoreTimeoutFunctions = function() {
        window.setTimeout = originalSetTimeout;
        window.clearTimeout = originalClearTimeout;
    };
}();

var id1 = setTimeout( alert.bind(null, "Hello from timeout 1"), 1000);
alert("Id1: " + id1);

var id2 = setTimeout( alert.bind(null, "Hello from timeout 2"), 2000);
alert("Id2: " + id2);

var id3 = setTimeout( alert.bind(null, "Hello from timeout 3"), 5000);
clearTimeout(id3);
alert("We should never see timeout 3");

restoreTimeoutFunctions();

var id4 = setTimeout(alert.bind(null, "Hello from timeout 4"), 3000);
alert("Id4: " + id4);