जावास्क्रिप्ट: सभी टाइमआउट साफ़ करें?


99

क्या किसी दिए गए विंडो से सभी समय को खाली करने का एक तरीका है? मुझे लगता है कि टाइमआउट windowऑब्जेक्ट में कहीं जमा हो जाते हैं, लेकिन इसकी पुष्टि नहीं कर सकते।

किसी भी क्रॉस ब्राउज़र समाधान का स्वागत है।



6
यार, यह सवाल 3 साल पहले का है और इसमें इसके शानदार जवाब हैं। इससे खिलवाड़ करने की जरूरत नहीं है।
मार्सियो

मैंने इसके लिए खोज की और दोनों को पाया। तुम्हारा बड़ा था इसलिए मैंने सोचा कि दो सवालों को एक में कम करने के लिए अच्छी हाउसकीपिंग होगी। मेरा सिर्फ एक वोट है; कुछ और लोगों को बंद करने के लिए वोट करने की आवश्यकता होगी, और डुप्लिकेट लिंक दूसरों की मदद कर सकता है।
बर्नहार्ड हॉफमैन

2
@ बर्नार्ड हॉफमैन मुझे यकीन नहीं है कि यह एक डुप्लिकेट प्रश्न के रूप में गिना जाता है अगर यह एक बेहतर जवाब मिला। 2010 से उस पर स्वीकृत उत्तर "नहीं" था।
रोबोटिक पुनर्जागरण

जवाबों:


148

वे विंडो ऑब्जेक्ट में नहीं हैं, लेकिन उनके पास आईडी हैं, जो (afaik) लगातार पूर्णांक हैं।

तो आप इस तरह से सभी समय समाप्त कर सकते हैं:

var id = window.setTimeout(function() {}, 0);

while (id--) {
    window.clearTimeout(id); // will do nothing if no timeout with id is present
}

1
क्या यह विनिर्देश का हिस्सा है, या क्या यह कार्यान्वयन-निर्भर हो सकता है?
तिखन जेल्विस

7
इसे 1 से शुरू करने की आवश्यकता नहीं है। एचटीएमएल 5 कल्पना कहती है "उपयोगकर्ता-एजेंट-परिभाषित पूर्णांक को शून्य से अधिक होने दें जो इस कॉल द्वारा सेट किए जाने के समय की पहचान करेगा।" जो गैर-निरंतर और गैर-छोटे पूर्णांकों सहित किसी भी सकारात्मक पूर्णांक को संभालने के लिए कमरे को छोड़ देता है।
माइक सैमुअल

3
यह बहुत चालाक है, लेकिन ओपी को शायद पूछना चाहिए कि क्या कोई बेहतर समाधान है जो सक्रिय टाइमर का ट्रैक रखता है।
जेसन हारविग

3
यह एक अनंत लूप नहीं है? सभी ब्राउज़र रेंडर नहीं करते हैं यदि (0) गलत है
ट्रैविस जे

2
जब से मैंने पूछा कि सभी टाइमआउट कैसे साफ़ करें, मैं इस उत्तर को स्वीकार कर रहा हूं। बहुत चालाक समाधान।
मार्सियो

79

मुझे लगता है कि इसे पूरा करने का सबसे आसान तरीका सभी setTimeoutपहचानकर्ताओं को एक सरणी में संग्रहीत करना होगा , जहां आप आसानी clearTimeout()से उन सभी पर पुनरावृति कर सकते हैं ।

var timeouts = [];
timeouts.push(setTimeout(function(){alert(1);}, 200));
timeouts.push(setTimeout(function(){alert(2);}, 300));
timeouts.push(setTimeout(function(){alert(3);}, 400));

for (var i=0; i<timeouts.length; i++) {
  clearTimeout(timeouts[i]);
}

14
इसमें केवल आपके द्वारा निर्धारित किए गए समाशोधन का बोनस (या संभावित दोष, मुझे लगता है) है , इसलिए आप अनजाने में अपने कोड से बाहर नहीं निकलेंगे।
तिखन जेल्विस

1
+1, सभी टाइमआउट को स्पष्ट नहीं करेगा, लेकिन एक बार में टाइमआउट के एक विशिष्ट समूह को साफ़ करने के लिए एक अच्छा समाधान है
marcio

1
यह सबसे अच्छा समाधान है क्योंकि यह बाहरी कोड को नहीं तोड़ेगा, लेकिन जब से मैंने पूछा कि सभी टाइमआउट को कैसे साफ़ किया जाए तो मैंने @ Pumbaa80 का जवाब स्वीकार कर लिया :)
marcio

2
@marcioAlmada अजीब है, लेकिन आप इस पर टिप्पणी करने के लिए वापस देखने के लिए शांत 2.5yrs बाद :) :)
माइकल Berkowski

6
शायद मैं सभी टाइमआउट और अंतराल को साफ करना चाहता हूं जब मैं एक वेबपेज में प्रवेश करता हूं जिसे मैं नियंत्रित नहीं करता हूं, क्योंकि उनके पास एक कष्टप्रद पॉप अप विज्ञापन है जो मेरे एडब्लॉकर के चलने तक शुरू नहीं होता है।
रोबॉटिकेनैसेन्स

12

मेरे पास Pumbaa80 के उत्तर के अतिरिक्त है जो पुराने IE के लिए विकसित करने वाले किसी व्यक्ति के लिए उपयोगी हो सकता है।

हां, सभी प्रमुख ब्राउज़र टाइमआउट आईडी को लगातार पूर्णांक के रूप में लागू करते हैं (जो विनिर्देश द्वारा आवश्यक नहीं है )। प्रारंभिक संख्या को अलग करके ब्राउज़र को ब्राउज़र में अलग करता है। ऐसा लगता है कि ओपेरा, सफारी, क्रोम और आईई> 8 1 से टाइमआउट आईडी शुरू करते हैं, 2 से जीको-आधारित ब्राउज़र और कुछ यादृच्छिक संख्या से आईई <= 8, जो कि टैब रीफ़्रेश होने पर जादुई रूप से सहेजे जाते हैं। आप इसे स्वयं खोज सकते हैं ।

वह सब जो आईई <= 8 में है, while (lastTimeoutId--)चक्र 8digits बार चल सकता है और " इस पृष्ठ पर एक स्क्रिप्ट इंटरनेट एक्सप्लोरर को धीरे-धीरे चलाने " का संदेश दिखा रहा है । इसलिए यदि आप सभी समयबाह्य आईडी को नहीं बचा सकते हैं या window.setTimeout को ओवरराइड नहीं करना चाहते हैं, तो आप किसी पृष्ठ पर पहली टाइमआउट आईडी को सहेजने और समय समाप्त होने तक उस पर विचार कर सकते हैं।

प्रारंभिक पृष्ठ लोड पर कोड निष्पादित करें:

var clearAllTimeouts = (function () {
    var noop = function () {},
        firstId = window.setTimeout(noop, 0);
    return function () {
        var lastId = window.setTimeout(noop, 0);
        console.log('Removing', lastId - firstId, 'timeout handlers');
        while (firstId != lastId)
            window.clearTimeout(++firstId);
    };
});

और फिर सभी लंबित समयबाह्य को साफ़ करें जो संभवतः विदेशी कोड द्वारा निर्धारित किया गया था जो आप चाहते हैं


प्लस एक और अधिक विस्तृत जानकारी को स्पष्ट करने के लिए।
संजय

8

कैसे एक वैश्विक सरणी में टाइमआउट आईडी स्टोर करें, और विंडो में फ़ंक्शन कॉल को प्रतिनिधि करने के लिए एक विधि को परिभाषित करें।

GLOBAL={
    timeouts : [],//global timeout id arrays
    setTimeout : function(code,number){
        this.timeouts.push(setTimeout(code,number));
    },
    clearAllTimeout :function(){
        for (var i=0; i<this.timeouts.length; i++) {
            window.clearTimeout(this.timeouts[i]); // clear all the timeouts
        }
        this.timeouts= [];//empty the id array
    }
};

3

आपको window.setTimeoutविधि को फिर से लिखना होगा और इसकी टाइमआउट आईडी को सहेजना होगा।

const timeouts = [];
const originalTimeoutFn = window.setTimeout;

window.setTimeout = function(fun, delay) { //this is over-writing the original method
  const t = originalTimeoutFn(fn, delay);
  timeouts.push(t);
}

function clearTimeouts(){
  while(timeouts.length){
    clearTimeout(timeouts.pop();
  }
}

3

सभी टाइमआउट को साफ़ करने के लिए उन्हें पहले "कैप्चर" किया जाना चाहिए :

नीचे दिए गए कोड को किसी अन्य स्क्रिप्ट से पहले रखें और यह मूल setTimeoutऔर के लिए एक आवरण फ़ंक्शन बनाएगा clearTimeout

ऑब्जेक्ट में एक नया clearTimeoutsतरीका जोड़ा जाएगा window, जो सभी (लंबित) टाइमआउट्स ( Gist लिंक ) को क्लियर करने की अनुमति देगा ।

अन्य उत्तरों में संभावित तर्कों के लिए पूर्ण समर्थन का अभाव हो सकता है। setTimeout

// isolated layer wrapper (for the local variables)
(function(_W){

var cache = [],                // will store all timeouts IDs
    _set = _W.setTimeout,      // save original reference
    _clear = _W.clearTimeout  // save original reference

// Wrap original setTimeout with a function 
_W.setTimeout = function( CB, duration, arg ){
    // also, wrap the callback, so the cache reference will be removed 
    // when the timeout has reached (fired the callback)
    var id = _set(function(){
        CB.apply(null, arguments)
        removeCacheItem(id)
    }, duration || 0, arg)

    cache.push( id ) // store reference in the cache array

    // id reference must be returned to be able to clear it 
    return id
}

// Wrap original clearTimeout with a function 
_W.clearTimeout = function( id ){
    _clear(id)
    removeCacheItem(id)
}

// Add a custom function named "clearTimeouts" to the "window" object
_W.clearTimeouts = function(){
    console.log("Clearing " + cache.length + " timeouts")
    cache.forEach(n => _clear(n))
    cache.length = []
}

// removes a specific id from the cache array 
function removeCacheItem( id ){
    var idx = cache.indexOf(id)

    if( idx > -1 )
        cache = cache.filter(n => n != id )
}

})(window);

2

पूर्णता के लिए, मैं एक सामान्य समाधान पोस्ट करना चाहता था जो दोनों को कवर करता है setTimeoutऔर setInterval

ऐसा लगता है कि ब्राउज़र दोनों के लिए ID के एक ही पूल का उपयोग कर सकते हैं, लेकिन कुछ उत्तरों से लेकर ClearTimeout और ClearInterval समान हैं? , यह स्पष्ट नहीं है कि एक ही फ़ंक्शन पर भरोसा करना clearTimeoutऔर clearIntervalप्रदर्शन करना सुरक्षित है या केवल उनके संबंधित टाइमर प्रकारों पर काम करना।

इसलिए, जब लक्ष्य सभी टाइमआउट और अंतराल को मारना है, तो यहां एक कार्यान्वयन है जो उन सभी का परीक्षण करने में असमर्थ होने पर कार्यान्वयन में थोड़ा अधिक रक्षात्मक हो सकता है:

function clearAll(windowObject) {
  var id = Math.max(
    windowObject.setInterval(noop, 1000),
    windowObject.setTimeout(noop, 1000)
  );

  while (id--) {
    windowObject.clearTimeout(id);
    windowObject.clearInterval(id);
  }

  function noop(){}
}

आप इसका उपयोग वर्तमान विंडो में सभी टाइमर साफ़ करने के लिए कर सकते हैं:

clearAll(window);

या आप इसे सभी टाइमर को खाली करने के लिए उपयोग कर सकते हैं iframe:

clearAll(document.querySelector("iframe").contentWindow);

यह ध्यान रखें कि यह दृष्टिकोण वीयू-क्ली-सर्विस वॉचर को नष्ट कर देता है ताकि आप सभी टाइमआउट और समय-समय पर सफाई करते समय हॉट-रीलोड न कर सकें। मुझे लगता है कि यह फ्रेमवर्क (कोणीय, प्रतिक्रिया, अंगारा आदि) के लिए अन्य हॉट रीलोड पर नजर रखने वालों के लिए समान है
माइकेल माइकेलहिडिस

1

मैं टाइपस्क्रिप्ट के साथ Vue का उपयोग करता हूं।

    private setTimeoutN;
    private setTimeoutS = [];

    public myTimeoutStart() {

        this.myTimeoutStop();//stop All my timeouts

        this.setTimeoutN = window.setTimeout( () => {
            console.log('setTimeout');
        }, 2000);

        this.setTimeoutS.push(this.setTimeoutN)//add THIS timeout ID in array

    }

    public myTimeoutStop() {

        if( this.setTimeoutS.length > 0 ) {
            for (let id in this.setTimeoutS) {
                console.log(this.setTimeoutS[id]);
                clearTimeout(this.setTimeoutS[id]);
            }
            this.setTimeoutS = [];//clear IDs array
        }
    }

0

वैश्विक टाइमआउट का उपयोग करें, जो आपके सभी अन्य कार्यों से प्राप्त होता है। यह सब कुछ तेजी से चलाएगा, और प्रबंधन करने में आसान होगा, हालांकि यह आपके कोड में कुछ अमूर्त जोड़ देगा।


मैं आपको पूरी तरह से नहीं समझता। आप set_timeoutवैश्विक समारोह के व्यवहार का विस्तार करने का मतलब है ? क्या आप एक उदाहरण कोड दे सकते हैं?
marcio

1
मेरा बस यही मतलब था कि आपके पास हर 50 मी में एक बार एक ग्लोबल टाइमआउट चल रहा है। हर दूसरे फंक्शन में एक टाइमिंग एलिमेंट की जरूरत होती है, फिर उसे ग्लोबल टाइमआउट से हड़प लेते हैं। Google ने इसे दक्षता के लिए स्विच किया, हालाँकि मैं अब इसे उद्धृत करने वाला लेख नहीं ढूँढ सकता।
ट्रैविस जे

0

हमने इस सटीक मुद्दे को हल करते हुए एक पैकेज प्रकाशित किया है।

npm install time-events-manager

कि के साथ, आप के माध्यम से सभी समय समाप्ति और अंतराल देख सकते हैं timeoutCollectionऔर intervalCollectionवस्तुओं। एक removeAllफ़ंक्शन भी है जो संग्रह और ब्राउज़र दोनों से सभी टाइमआउट / अंतराल को साफ़ करता है।


0

यह बहुत देर हो चुकी है ... लेकिन:

मूल रूप से, setTimeout / setInterval ID लगातार क्रम में जाती है, इसलिए केवल उच्चतम ID प्राप्त करने के लिए एक डमी टाइमआउट फ़ंक्शन बनाएं, फिर उससे कम सभी ID पर अंतराल साफ़ करें।

const highestId = window.setTimeout(() => {
  for (let i = highestId; i >= 0; i--) {
    window.clearInterval(i);
  }
}, 0);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.