पहली बार में देरी के बिना setInterval फ़ंक्शन निष्पादित करें


341

यह कॉन्फ़िगर करने का एक तरीका है setInterval जावास्क्रिप्ट विधि करने का तरीका तुरंत निष्पादित करने के लिए और फिर टाइमर के साथ निष्पादित होता है


4
हालांकि मूल रूप से नहीं। आप functionएक बार कॉल करने की कोशिश कर सकते हैं और फिर कर सकते हैंsetInterval()
Mrchief

जवाबों:


519

केवल पहली बार सीधे फंक्शन को कॉल करना सबसे सरल है:

foo();
setInterval(foo, delay);

हालांकि बचने के अच्छे कारण हैं setInterval- विशेष रूप से कुछ परिस्थितियों में setIntervalघटनाओं का एक पूरा लोड बिना किसी देरी के तुरंत एक दूसरे के बाद आ सकता है। एक और कारण यह है कि यदि आप लूप को रोकना चाहते हैं, तो आपको स्पष्ट रूप से कॉल करना होगा, clearIntervalजिसका मतलब है कि आपको मूल setIntervalकॉल से लौटे हैंडल को याद रखना होगा ।

इसलिए एक वैकल्पिक तरीका इसके बजाय fooबाद में कॉल के लिए खुद को ट्रिगर setTimeoutकरना है:

function foo() {
   // do stuff
   // ...

   // and schedule a repeat
   setTimeout(foo, delay);
}

// start the cycle
foo();

यह गारंटी देता है कि कॉल के बीच कम से कम अंतराल है delay। यदि आवश्यक हो तो लूप को रद्द करना भी आसान हो जाता है - setTimeoutजब आपके लूप की समाप्ति की स्थिति पूरी हो जाती है तो आप कॉल नहीं करते हैं ।

बेहतर अभी तक, आप एक तुरंत लागू फ़ंक्शन अभिव्यक्ति में सभी को लपेट सकते हैं जो फ़ंक्शन बनाता है, जो तब खुद को फिर से ऊपर कहता है, और स्वचालित रूप से लूप शुरू करता है:

(function foo() {
    ...
    setTimeout(foo, delay);
})();

जो कार्य को परिभाषित करता है और चक्र को एक बार में शुरू करता है।


5
आप क्यों पसंद करते हैं setTimeout?
सांग्युन ली

19
@Sangdol क्योंकि यह सुनिश्चित करता है कि टाइमर इवेंट "स्टैक" नहीं हैं यदि वे अनप्रोसेस्ड हैं। कुछ परिस्थितियों में setIntervalघटनाओं का एक पूरा लोड बिना किसी देरी के एक दूसरे के तुरंत बाद आ सकता है।
अलनीतक

8
किसी प्रकार का परीक्षण होना चाहिए जो आपको थका हुआ होने पर पोस्ट नहीं करने देता है
जेम्स

3
यदि मैं setTimeoutविधि का उपयोग करता हूं तो मैं फ़ंक्शन को कैसे रोकूं?
गौरव भोर

6
@DaveMunger नहीं, क्योंकि यह वास्तव में पुनरावर्ती नहीं है - यह केवल "छद्म-पुनरावर्ती" है। "पुनरावर्ती" कॉल तब तक नहीं होती है जब तक कि ब्राउज़र इवेंट लूप में वापस नहीं आ जाता है, जिस बिंदु पर कॉल स्टैक पूरी तरह से अवांछित है।
अलनीतक

210

मुझे यकीन नहीं है कि मैं आपको सही तरीके से समझ रहा हूं, लेकिन आप आसानी से ऐसा कुछ कर सकते हैं:

setInterval(function hello() {
  console.log('world');
  return hello;
}(), 5000);

स्पष्ट रूप से ऐसा करने के कई तरीके हैं, लेकिन यह सबसे संक्षिप्त तरीका है जिसके बारे में मैं सोच सकता हूं।


16
यह एक अच्छा जवाब है क्योंकि यह एक नामित कार्य है जो तुरंत निष्पादित होता है और स्वयं भी वापस आ जाता है। ठीक वही जो मेरे द्वारा खोजा जा रहा था।
jmort253

41
निश्चित रूप से एक शांत समाधान है, लेकिन भविष्य में पढ़ने वाले लोगों के लिए भ्रम की संभावना है।
दीपक जॉय

4
आपको इसे 'हैलो' नाम देने की आवश्यकता नहीं है। आप के बजाय एक गुमनाम समारोह के साथ arguments.callee लौट सकते हैं और है ही
JochenJung

10
@ जोचेनजंग ES5 arguments.calleeसख्त मोड में उपलब्ध नहीं है
Alnitak

3
यह एक प्रकार का जावास्क्रिप्ट कोड है जो अधिकांश नए JS प्रोग्रामर को भ्रमित करेगा जो अन्य भाषाओं से आए हैं। अगर आपकी कंपनी के पास बहुत सारे जेएस कर्मी नहीं हैं और आप नौकरी की सुरक्षा चाहते हैं, तो इस तरह से सामान का एक गुच्छा लिखें।
इयान

13

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

यहाँ इस समस्या का समाधान है:

function setIntervalImmediately(func, interval) {
  func();
  return setInterval(func, interval);
}

इस समाधान का लाभ:

  • मौजूदा कोड का उपयोग करके setIntervalआसानी से प्रतिस्थापन द्वारा अनुकूलित किया जा सकता है
  • सख्त मोड में काम करता है
  • यह मौजूदा नामित कार्यों और क्लोजर के साथ काम करता है
  • आप अभी भी वापसी मूल्य का उपयोग कर सकते हैं और इसे clearInterval()बाद में पास कर सकते हैं

उदाहरण:

// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
        console.log('hello');
    }, 1000);

// clear interval after 4.5 seconds
setTimeout( _ => {
        clearInterval(myInterval);
    }, 4500);

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

var setIntervalOrig = setInterval;

setInterval = function(func, interval) {
    func();
    return setIntervalOrig(func, interval);
}

फिर भी, ऊपर सूचीबद्ध सभी फायदे यहां लागू होते हैं लेकिन कोई प्रतिस्थापन आवश्यक नहीं है।


मैं इस समाधान पर समाधान पसंद करता हूं setTimeoutक्योंकि यह एक setIntervalवस्तु देता है । कॉलिंग फ़ंक्शंस से बचने के लिए जो शायद बाद में कोड में हैं और इसलिए वर्तमान समय में अपरिभाषित हैं, मैं पहले फ़ंक्शन कॉल को setTimeoutइस तरह से फ़ंक्शन में लपेटता हूं : setTimeout(function(){ func();},0);पहले फ़ंक्शन को वर्तमान प्रसंस्करण चक्र के बाद कहा जाता है, जो तुरंत भी है , लेकिन है अधिक त्रुटि साबित हुई।
पेन्सन

8

आप setInterval()उस फ़ंक्शन में लपेट सकते हैं जो उस व्यवहार को प्रदान करता है:

function instantGratification( fn, delay ) {
    fn();
    setInterval( fn, delay );
}

... तो इसे इस तरह उपयोग करें:

instantGratification( function() {
    console.log( 'invoked' );
}, 3000);

5
मुझे लगता है कि आपको वापसी करना चाहिए क्या सेटअंटरवल रिटर्न। ऐसा इसलिए है क्योंकि अन्यथा आप clearInterval का उपयोग नहीं कर सकते हैं।
हेनरिक आर

5

यदि आपको इसकी आवश्यकता है, तो इसे सुंदर बनाने के लिए एक आवरण है:

(function() {
    var originalSetInterval = window.setInterval;

    window.setInterval = function(fn, delay, runImmediately) {
        if(runImmediately) fn();
        return originalSetInterval(fn, delay);
    };
})();

SetInterval के तीसरे तर्क को सही पर सेट करें और यह setInterval को कॉल करने के तुरंत बाद पहली बार चलेगा:

setInterval(function() { console.log("hello world"); }, 5000, true);

या तीसरे तर्क को छोड़ दें और यह अपने मूल व्यवहार को बनाए रखेगा:

setInterval(function() { console.log("hello world"); }, 5000);

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


9
देशी ब्राउज़र फ़ंक्शंस को ओवरराइड करना बहुत ही भयानक है क्योंकि यह चश्मा बदलने पर अन्य सह-कोडिंग कोड को तोड़ सकता है। वास्तव में, setInterval में वर्तमान में अधिक पैरामीटर हैं: developer.mozilla.org/en-US/docs/Web/API/WindowTimers/…
elxel Costas Pena

2

किसी के लिए बाहरी को thisअंदर लाने की जरूरत है जैसे कि यह एक तीर का कार्य है।

(function f() {
    this.emit("...");
    setTimeout(f.bind(this), 1000);
}).bind(this)();

यदि उपर्युक्त कचरा आपको परेशान करता है, तो आप इसके बजाय एक बंद कर सकते हैं।

(that => {
    (function f() {
        that.emit("...");
        setTimeout(f, 1000);
    })();
})(this);

या शायद अपने कोड के आधार पर डेकोरेटर का उपयोग करने@autobind पर विचार करें।


1

मैं निम्नलिखित अनुक्रम में फ़ंक्शन को कॉल करने का सुझाव दूंगा

var _timer = setInterval(foo, delay, params);
foo(params)

आप _timerफू को भी पास कर सकते हैं , यदि आप clearInterval(_timer)एक निश्चित शर्त पर करना चाहते हैं

var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);

क्या आप इसे अधिक गहराई से समझा सकते हैं?
पॉलीडुकस

आप दूसरी कॉल से टाइमर सेट करते हैं, पहली बार आप सीधे fn को कॉल करते हैं।
जयंत वार्ष्णेय

1

यहाँ सभी गड़बड़ के बिना नौसिखियों के लिए एक सरल संस्करण है। यह सिर्फ फ़ंक्शन की घोषणा करता है, इसे कॉल करता है, फिर अंतराल शुरू करता है। बस।

//Declare your function here
function My_Function(){
  console.log("foo");
}    

//Call the function first
My_Function();

//Set the interval
var interval = window.setInterval( My_Function, 500 );


1
यह वही है जो स्वीकृत उत्तर पहली कुछ पंक्ति में करता है। यह उत्तर कुछ नया कैसे जोड़ता है?
Dan Dascalescu

ऐसा नहीं करने के लिए कहा गया स्वीकृत उत्तर आगे बढ़ता है। स्वीकृत उत्तर के बारे में मेरी प्रतिक्रिया बताती है कि यह अभी भी एक वैध तरीका क्यों है। ओपी विशेष रूप से अपने पहले कॉल पर setInterval के फ़ंक्शन को कॉल करने के लिए कहता है, लेकिन स्वीकृत उत्तर डायवर्ट सेटऑउटआउट के लाभों के बारे में बात करने के लिए कहता है।
पोलीडुक

0

इस समस्या को हल करने के लिए, मैं पृष्ठ लोड होने के बाद पहली बार फ़ंक्शन चलाता हूं।

function foo(){ ... }

window.onload = function() {
   foo();
};

window.setInterval(function()
{
    foo(); 
}, 5000);

0

एक सुविधाजनक npm पैकेज है जिसे FirstInterval कहा जाता है (पूर्ण प्रकटीकरण, यह मेरा है) ।

यहां कई उदाहरणों में पैरामीटर हैंडलिंग शामिल नहीं है, और setIntervalकिसी भी बड़ी परियोजना में डिफ़ॉल्ट व्यवहार को बदलना बुराई है। डॉक्स से:

यह पैटर्न

setInterval(callback, 1000, p1, p2);
callback(p1, p2);

के समान है

firstInterval(callback, 1000, p1, p2);

यदि आप ब्राउज़र में पुराने स्कूल हैं और निर्भरता नहीं चाहते हैं, तो यह कोड से आसान कट-एंड-पेस्ट है


0

// YCombinator
function anonymous(fnc) {
  return function() {
    fnc.apply(fnc, arguments);
    return fnc;
  }
}

// Invoking the first time:
setInterval(anonymous(function() {
  console.log("bar");
})(), 4000);

// Not invoking the first time:
setInterval(anonymous(function() {
  console.log("foo");
}), 4000);
// Or simple:
setInterval(function() {
  console.log("baz");
}, 4000);

ठीक है, यह इतना जटिल है, इसलिए, मुझे इसे और सरल बनाने दें:

function hello(status ) {    
  console.log('world', ++status.count);
  
  return status;
}

setInterval(hello, 5 * 1000, hello({ count: 0 }));


यह बहुत अधिक इंजीनियर है।
पॉलीडुकस

0

आप एक बहुत छोटा प्रारंभिक विलंब-समय (जैसे 100) सेट कर सकते हैं और इसे फ़ंक्शन के भीतर अपने वांछित विलंब-समय पर सेट कर सकते हैं:

var delay = 100;

function foo() {
  console.log("Change initial delay-time to what you want.");
  delay = 12000;
  setTimeout(foo, delay);
}


-2

आपके फ़ंक्शन के तत्काल अतुल्यकालिक कॉल के साथ एक समस्या है, क्योंकि मानक सेटटाइमआउट / सेटइंटरवल में कई मिलीसेकंड के बारे में न्यूनतम समय समाप्त होता है, भले ही आप इसे सीधे सेट करें 0. यह एक ब्राउज़र विशिष्ट कार्य के कारण होता है।

क्रोम, सफारी, ओपेरा में एक वास्तविक शून्य विलंब विच कोड के साथ कोड का एक उदाहरण

function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}

आप अधिक जानकारी यहाँ पा सकते हैं

और पहले मैनुअल कॉल के बाद आप अपने फ़ंक्शन के साथ एक अंतराल बना सकते हैं।


-10

वास्तव में सबसे तेज करना है

interval = setInterval(myFunction(),45000)

यह myfunction को बुलाएगा, और फिर इसे हर 45 सेकंड में अगियायन करेगा जो करने से अलग है

interval = setInterval(myfunction, 45000)

जो इसे कॉल नहीं करेगा, लेकिन इसे केवल शेड्यूल करें


आपको वह कहां से मिला?
केन शार्प

2
यह तभी काम करता है जब myFunction()वह खुद लौट आए। प्रत्येक फ़ंक्शन को संशोधित करने के बजाय setIntervalइसे कॉल करने के लिए एक बेहतर तरीका है कि setIntervalएक बार लपेटें जैसे कि अन्य उत्तर प्रस्तावित कर रहे हैं।
जेन्स विर्थ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.