clearTimeout without ID

2020-03-25 00:42发布

Is there any way to clear setTimeout() if it doesn't have an explicit ID? The problem is I'm not allowed to change some code that already ran and set the timers without any handler.

Does JS set 'anonymous handlers' to them? Are these timers stored anywhere accessible? Can I get any of those properties (the function the timer is about to call? the time it'll be called?)

4条回答
The star\"
2楼-- · 2020-03-25 01:18

No. The clearTimeout method requires that the ID returned from setTimeout be provided in order to remove the timeout.

Could you post some more information about your scenario? Perhaps some code snippets? There may be a way to work around the scenario.

查看更多
该账号已被封号
3楼-- · 2020-03-25 01:24

No. But you could make the handler check whether it should still handle the event (with a boolean variable).

查看更多
太酷不给撩
4楼-- · 2020-03-25 01:34

Nope, you can't without a reference. You could try something REALLY hacky (don't do this! it's just an illustration of hackyness) to clear all timeouts:

for(var i=0; i<100000; i++) clearTimeout(i);

but again that's not foolproof and well beyond hacky.

Solution? Fight be able to change the source, so you can do this properly - or see if you can override the function creating the timer.

查看更多
何必那么认真
5楼-- · 2020-03-25 01:36

Another possible hacky approach is to throw an error from somewhere within the timeout. For this to work, the error must (a) not be caught within a try-catch block; and (b) occur before the timeout has had a chance to take the actions you dislike. Depending on the content of the timeout this may be easy, hard, or impossible.

For example, if the timeout is registered like this:

setTimeout(function(){
   if(document.URL.toUpperCase() === "..."){
      // do something that you don't like
   }
}, 60000);

then the only way (I think) that you can throw an error is to monkey-patch the function String.prototype.toUpperCase, and check whether the calling function is the offending timeout. You can't make this check with absolute certainty, but (new Error).stack will certainly come in handy...you can compare against the expected stack trace. You can do similar things by monkey patching property getters, or perhaps by setting a specific object to undefined. ES6 might give some additional possibilities.

This is decidedly hacky, and it doesn't actually clear the timeout, it only prevents it from having any outwardly observable behavior. However, it may just do the trick! (If performance is relevant, then be careful with your monkey-patching.)

查看更多
登录 后发表回答