2009-12-24 19 views
16

जावास्क्रिप्ट में window.setTimeout (और संबंधित setInterval) समारोह आप समय निर्धारित करना एक समारोह भविष्य में कभी निष्पादित करने की अनुमति देता है:जावास्क्रिप्ट प्राप्त करें टाइमआउट?

id = setTimeout(function, delay); 

जहां "देरी" भविष्य में मिलीसेकेंड की संख्या, जिस पर आप करना चाहते हैं समारोह कहा जाता है। इस समय समाप्त होने से पहले, आप का उपयोग कर घड़ी रोक सकते हैं:

clearTimeout(id); 

मैं क्या चाहता हूँअद्यतन टाइमर है। मैं टाइमर को अग्रिम या मंद करने में सक्षम होना चाहता हूं ताकि फ़ंक्शन को x मिलीसेकंड जल्दी या बाद में मूल रूप से शेड्यूल किया जा सके।

अगर वहाँ थे एक getTimeout विधि, आप की तरह कुछ कर सकता है:

originally_scheduled_time = getTimeout(id); 
updateTimeout(id, originally_schedule_time + new_delay); // change the time 

लेकिन जहां तक ​​मैं getTimeout या एक मौजूदा टाइमर अद्यतन करने के लिए किसी भी तरह से ऐसा कुछ नहीं है बता सकते हैं के रूप में।

क्या निर्धारित अलार्म की सूची तक पहुंचने और उन्हें संशोधित करने का कोई तरीका है?

क्या कोई बेहतर तरीका है?

धन्यवाद!

+5

आपका स्वागत है। महान पहला सवाल। – Sampson

+0

मुझे विश्वास है कि आप एक ब्राउज़र स्वतंत्र समाधान की तलाश में थे (और मिला)। – jensgram

उत्तर

14

यदि आप वास्तव में इस तरह की कार्यक्षमता चाहते हैं, तो आपको इसे स्वयं लिखने की आवश्यकता होगी।

आप setTimeout कॉल के लिए एक आवरण, कि एक वस्तु आप टाइमर "स्थगित" करने के लिए उपयोग कर सकते हैं वापस आ जाएगी बना सकते हैं:

function setAdvancedTimer(f, delay) { 
    var obj = { 
    firetime: delay + (+new Date()), // the extra + turns the date into an int 
    called: false, 
    canceled: false, 
    callback: f 
    }; 
    // this function will set obj.called, and then call the function whenever 
    // the timeout eventually fires. 
    var callfunc = function() { obj.called = true; f(); }; 
    // calling .extend(1000) will add 1000ms to the time and reset the timeout. 
    // also, calling .extend(-1000) will remove 1000ms, setting timer to 0ms if needed 
    obj.extend = function(ms) { 
    // break early if it already fired 
    if (obj.called || obj.canceled) return false; 
    // clear old timer, calculate new timer 
    clearTimeout(obj.timeout); 
    obj.firetime += ms; 
    var newDelay = obj.firetime - new Date(); // figure out new ms 
    if (newDelay < 0) newDelay = 0; 
    obj.timeout = setTimeout(callfunc, newDelay); 
    return obj; 
    }; 
    // Cancel the timer... 
    obj.cancel = function() { 
    obj.canceled = true; 
    clearTimeout(obj.timeout); 
    }; 
    // call the initial timer... 
    obj.timeout = setTimeout(callfunc, delay); 
    // return our object with the helper functions.... 
    return obj; 
} 

var d = +new Date(); 
var timer = setAdvancedTimer(function() { alert('test'+ (+new Date() - d)); }, 1000); 

timer.extend(1000); 
// should alert about 2000ms later 
+0

+1 अच्छा उदाहरण। – jensgram

-2

एक संभावना यह इस तरह हो सकता है:

if (this condition true) 
{ 
    setTimeout(function, 5000); 
} 
elseif (this condition true) 
{ 
    setTimeout(function, 10000); 
} 
else 
{ 
    setTimeout(function, 1000); 
} 

यह कैसे आप अपने शर्तों या तर्क का निर्माण अपने पर निर्भर है। धन्यवाद

4

मुझे विश्वास नहीं है। एक बेहतर तरीका आपके स्वयं के रैपर को लिखना हो सकता है जो आपके टाइमर स्टोर करता है (func-ref, देरी, और टाइमस्टैम्प)। इस तरह आप इसे समाशोधन करके टाइमर अपडेट करने का नाटक कर सकते हैं और एक अपडेट की देरी के साथ प्रतिलिपि की गणना कर सकते हैं।

+0

@ जेन्सग्राम: इसका एक उदाहरण सराहना की जाएगी :) – Sarfraz

+0

+1 - मैं जल्द ही पोस्ट करूँगा लेकिन मैं एक उदाहरण लिख रहा था;) – gnarf

+0

धन्यवाद - यह उत्तर लगता है। मजेदार है कि {सेट, स्पष्ट} {टाइमआउट, अंतराल} एपीआई अमीर नहीं है। – nibot

0

यह हो सकता है नहीं तो आप वास्तव में क्या चाहते हैं, लेकिन एक भी देखो ले , शायद आप इसे अपने लाभ के लिए उपयोग कर सकते हैं।

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

समाधान getDelayedHandlers नामक एक फ़ंक्शन है।

var handlers = handleMenu.getDelayedHandlers({ 
    in: 200, // 'in' timeout 
    out: 300, // 'out' timeout 
}); 

handlers एक वस्तु है कि जब जा रहा है कि दो हैंडलर कार्यों में शामिल हो जाता है: उदाहरण के लिए यदि आप एक समारोह है कि पता चलता है और एक मेनू

function handleMenu(show) { 
    if (show) { 
     // This part shows the menu 
    } else { 
     // This part hides the menu 
    } 
} 

फिर आप ऐसा करके इसके लिए देरी संचालकों बना सकते हैं छुपाता है जिसे किसी अन्य का टाइमआउट रद्द कर दिया जाता है।

var element = $('menu_element'); 
element.observe('mouseover', handlers.over); 
element.observe('mouseout', handlers.out); 

पीएस काम करने के लिए इस समाधान के लिए आपको curry फ़ंक्शन के साथ फ़ंक्शन ऑब्जेक्ट को विस्तारित करने की आवश्यकता है, जो स्वचालित रूप से Prototype में किया जाता है।

2

एक और आवरण:

function SpecialTimeout(fn, ms) { 
    this.ms = ms; 
    this.fn = fn; 
    this.timer = null; 
    this.init(); 
} 

SpecialTimeout.prototype.init = function() { 
    this.cancel(); 
    this.timer = setTimeout(this.fn, this.ms); 
    return this; 
}; 

SpecialTimeout.prototype.change = function(ms) { 
    this.ms += ms; 
    this.init(); 
    return this; 
}; 

SpecialTimeout.prototype.cancel = function() { 
    if (this.timer !== null) { 
     clearTimeout(this.timer); 
     this.timer = null; 
    } 
    return this; 
}; 

उपयोग: StackOverflow को

var myTimer = new SpecialTimeout(function(){/*...*/}, 10000); 

myTimer.change(-5000); // Retard by five seconds 
myTimer.change(5000); // Extend by five seconds 
myTimer.cancel(); // Cancel 
myTimer.init(); // Restart 

myTimer.change(1000).init(); // Chain! 
+0

नाइस रैपर, (मेरा से ज्यादा क्लीनर) लेकिन 'एमएस' संपत्ति किसी भी समय ध्यान में नहीं रखती है जो पहले से ही पारित हो सकती है या नहीं ... सुनिश्चित नहीं है कि ओपी को यह – gnarf

+0

अच्छी तरह लिखित कोड की आवश्यकता है, लेकिन " बदलें "विधि को पहले से ही समाप्त होने वाले समय के लिए सही ढंग से क्षतिपूर्ति करने की आवश्यकता है। मुझे लगता है कि डेट.getTime को कॉल के माध्यम से जोड़ना आसान होगा। फायरिंग तक देरी को संग्रहित करने के बजाय, स्पेशलटाइम उस पूर्ण समय को स्टोर करेगा जिस पर इसे आग लगाना है। – nibot

संबंधित मुद्दे