जब यह चल रहा हो तब सेटइंटरवल के अंतराल को बदलना


161

मैंने एक जावास्क्रिप्ट फ़ंक्शन लिखा है जो एक निश्चित संख्या में पुनरावृत्तियों के लिए एक स्ट्रिंग को एक सेकंड के हर दसवें में हेरफेर करने के लिए सेटइंटरवल का उपयोग करता है।

function timer() {
    var section = document.getElementById('txt').value;
    var len = section.length;
    var rands = new Array();

    for (i=0; i<len; i++) {
        rands.push(Math.floor(Math.random()*len));
    };

    var counter = 0
    var interval = setInterval(function() {
        var letters = section.split('');
        for (j=0; j < len; j++) {
            if (counter < rands[j]) {
                letters[j] = Math.floor(Math.random()*9);
            };
        };
        document.getElementById('txt').value = letters.join('');
        counter++

        if (counter > rands.max()) {
            clearInterval(interval);
        }
    }, 100);
};

एक विशिष्ट संख्या पर अंतराल सेट होने के बजाय, मैं हर बार इसे अद्यतन करना चाहूंगा, यह एक काउंटर पर आधारित है। इसलिए इसके बजाय:

var interval = setInterval(function() { ... }, 100);

यह कुछ इस तरह होगा:

var interval = setInterval(function() { ... }, 10*counter);

दुर्भाग्य से, यह काम नहीं किया। ऐसा लग रहा था कि "10 * काउंटर" 0 के बराबर है।

तो, अनाम फ़ंक्शन चलने पर मैं हर बार अंतराल को कैसे समायोजित कर सकता हूं?

जवाबों:


107

setTimeout()इसके बजाय उपयोग करें । कॉलबैक फिर अगली टाइमआउट फायरिंग के लिए जिम्मेदार होगा, जिस बिंदु पर आप समय बढ़ा सकते हैं या अन्यथा हेरफेर कर सकते हैं।

संपादित करें

यहां एक सामान्य फ़ंक्शन है जिसे आप किसी भी फ़ंक्शन कॉल के लिए "डीटेलरिंग" टाइमआउट लागू करने के लिए उपयोग कर सकते हैं।

function setDeceleratingTimeout(callback, factor, times)
{
    var internalCallback = function(tick, counter) {
        return function() {
            if (--tick >= 0) {
                window.setTimeout(internalCallback, ++counter * factor);
                callback();
            }
        }
    }(times, 0);

    window.setTimeout(internalCallback, factor);
};

// console.log() requires firebug    
setDeceleratingTimeout(function(){ console.log('hi'); }, 10, 10);
setDeceleratingTimeout(function(){ console.log('bye'); }, 100, 10);

1
कॉलबैक से, क्या आपका मतलब है कि फ़ंक्शन की अंतिम पंक्ति खुद को एक सेटटाइमआउट (..., newInterval) के साथ पुनरावर्ती बनाती है?
मार्क

1
मुझे लगता है कि वह क्या मतलब है। मैंने बस कोशिश की और यह काम करने लगता है। धन्यवाद दोस्तों!
जो डि स्टेफानो

2
केवल 9 हाय देता है :) --tसंभवतः t-- jsfiddle.net/albertjan/by5fd
अल्बर्टन

1
यदि timesआप बहुत बड़े हैं तो यह एक बहुत बड़ी त्रुटि होने का जोखिम नहीं उठाते हैं ?
एंड्रे सी। एंडरसन

4
यहाँ नाइटपिक होने के नाते, लेकिन मुझे लगता है कि कोड को पढ़ना बहुत कठिन है। यदि आप अगली पंक्ति के ब्रेसिज़ का उपयोग करने वाले हैं, तो कम से कम 4-8-स्थान इंडेंटेशन का उपयोग करने की शालीनता रखें या कभी भी 2 सेंट से आगे न जाएं। IMO इस संस्करण को पढ़ना बहुत आसान है। इसके अलावा के नाम को ध्यान में रखना tकरने के लिए tickहै, जो जो कुछ भी "टी" के लिए खड़े करने के लिए माना जाता है के रूप में मेरे सबसे अच्छे अनुमान था। tएक बहुत बुरा परिवर्तनशील नाम है।
ब्रैडेन बेस्ट

124

आप एक अनाम फ़ंक्शन का उपयोग कर सकते हैं:

var counter = 10;
var myFunction = function(){
    clearInterval(interval);
    counter *= 10;
    interval = setInterval(myFunction, counter);
}
var interval = setInterval(myFunction, counter);

अद्यतन: जैसा कि ए। वोल्फ द्वारा सुझाव दिया गया है, setTimeoutकी आवश्यकता से बचने के लिए उपयोग करें clearInterval

var counter = 10;
var myFunction = function() {
    counter *= 10;
    setTimeout(myFunction, counter);
}
setTimeout(myFunction, counter);

5
खैर RozzA, मेरा जवाब 16 सितंबर 11 और user28958 अगस्त 22 '13 को पोस्ट किया गया था, इसलिए मैं "प्रतिनिधि" धन्यवाद लूंगा!
निक

12
आप एक अंतराल का उपयोग क्यों कर रहे हैं, इसे साफ करने की आवश्यकता के बिना एक सरल टाइमआउट बेहतर होगा। जैसे: jsfiddle.net/fgs5nwgn
A. वोल्फ

4
मैं प्रश्न के संदर्भ से चिपका हुआ था। सेटटाइमआउट निश्चित रूप से काम करेगा
निक

24

मुझे यह सवाल पसंद है - मुझ में एक छोटी सी टाइमर वस्तु से प्रेरित:

window.setVariableInterval = function(callbackFunc, timing) {
  var variableInterval = {
    interval: timing,
    callback: callbackFunc,
    stopped: false,
    runLoop: function() {
      if (variableInterval.stopped) return;
      var result = variableInterval.callback.call(variableInterval);
      if (typeof result == 'number')
      {
        if (result === 0) return;
        variableInterval.interval = result;
      }
      variableInterval.loop();
    },
    stop: function() {
      this.stopped = true;
      window.clearTimeout(this.timeout);
    },
    start: function() {
      this.stopped = false;
      return this.loop();
    },
    loop: function() {
      this.timeout = window.setTimeout(this.runLoop, this.interval);
      return this;
    }
  };

  return variableInterval.start();
};

उदाहरण का उपयोग करें

var vi = setVariableInterval(function() {
  // this is the variableInterval - so we can change/get the interval here:
  var interval = this.interval;

  // print it for the hell of it
  console.log(interval);

  // we can stop ourselves.
  if (interval>4000) this.stop();

  // we could return a new interval after doing something
  return interval + 100;
}, 100);  

// we can change the interval down here too
setTimeout(function() {
  vi.interval = 3500;
}, 1000);

// or tell it to start back up in a minute
setTimeout(function() {
  vi.interval = 100;
  vi.start();
}, 60000);

4
धन्यवाद - मुझे कुछ इसी तरह के काम के लिए मुझे सही दिशा में सेट करें।
कर्नल स्पॉन्ज

सरल और प्रभावी। धन्यवाद!
जेस्टर

18

मैं मूल पोस्टर के रूप में एक ही सवाल था, यह एक समाधान के रूप में किया था। यकीन नहीं होता कि यह कितना कारगर है ...।

interval = 5000; // initial condition
var run = setInterval(request , interval); // start setInterval as "run"

    function request() { 

        console.log(interval); // firebug or chrome log
        clearInterval(run); // stop the setInterval()

         // dynamically change the run interval
        if(interval>200 ){
          interval = interval*.8;
        }else{
          interval = interval*1.2;
        }

        run = setInterval(request, interval); // start the setInterval()

    }

मुझे यह उत्तर बेहतर लगा क्योंकि यह वास्तव में ओपी (और मेरे) प्रश्न का उत्तर देता है। सेटटाइमआउट में देरी होने के अधीन है (100% सीपीयू उपयोग, अन्य स्क्रिप्ट, आदि) जहां
सेटइंटरवल

8
मुझे 99% यकीन है कि आपका दावा setIntervalगलत है @RozzA - यह अभी भी किसी भी अन्य जावास्क्रिप्ट के समान देरी के अधीन है, और लगभग हर ब्राउज़र भी सेट करता है InInvalval 4ms। क्या आपके पास इस या कुछ के बारे में एक पोस्ट का लिंक है?
गर्नफ

9

यह ऐसा करने का मेरा तरीका है, मैं setTimeout का उपयोग करता हूं:

var timer = {
    running: false,
    iv: 5000,
    timeout: false,
    cb : function(){},
    start : function(cb,iv){
        var elm = this;
        clearInterval(this.timeout);
        this.running = true;
        if(cb) this.cb = cb;
        if(iv) this.iv = iv;
        this.timeout = setTimeout(function(){elm.execute(elm)}, this.iv);
    },
    execute : function(e){
        if(!e.running) return false;
        e.cb();
        e.start();
    },
    stop : function(){
        this.running = false;
    },
    set_interval : function(iv){
        clearInterval(this.timeout);
        this.start(false, iv);
    }
};

उपयोग:

timer.start(function(){
    console.debug('go');
}, 2000);

timer.set_interval(500);

timer.stop();

+1, मैंने अपने उद्देश्यों के लिए इसे थोड़ा संशोधित किया, इसलिए मैं कई चर अंतरालों का उपयोग कर सकता हूं - jsfiddle.net/h70mzvdq
डलास

set_intervalजब तक नया अंतराल पुराने वाले से छोटा नहीं होता है तब तक एक नया निष्पादन नहीं करने के लिए फ़ंक्शन को संशोधित किया गया है ..if (iv < this.iv) { clearInterval(this.timeout); this.start(false, iv); } else { this.iv = iv; }
डलास

9

एक बहुत ही सरल तरीका होगा ifकि रिफ्रेश किए गए फ़ंक्शन में एक स्टेटमेंट हो और नियमित समय के अंतराल पर आपकी कमांड निष्पादित करने के लिए एक नियंत्रण हो। निम्नलिखित उदाहरण में, मैं हर 2 सेकंड में एक अलर्ट चलाता हूं और अंतराल ( intrv) को गतिशील रूप से बदला जा सकता है ...

var i=1;
var intrv=2; // << control this variable

var refreshId = setInterval(function() {
  if(!(i%intrv)) {
    alert('run!');
  }
  i++;
}, 1000);

यह मेरा निजी पसंदीदा भी है। छोटा सा, सरल, विस्तारणीय।
पुरुष मोगरबी

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

यह अच्छा है, लेकिन यह उन क्षणों में अंतराल को आग लगा देता है जिनकी आपको आवश्यकता नहीं है ... यह भी थोड़ा अपठनीय है। इन कारणों से मैं व्यक्तिगत रूप से सेटटाइमआउट करना पसंद करूंगा।
कोकोडको

4

यह शुरू किया जा सकता है लेकिन आप चाहते हैं। टाइमआउट वह विधि है जिसका उपयोग मैंने इसे घंटे के शीर्ष पर रखने के लिए किया था।

घंटे पर कोड ब्लॉक शुरू करने के लिए मुझे हर घंटे की आवश्यकता थी। तो यह सर्वर स्टार्टअप पर शुरू होता है और प्रति घंटा अंतराल चलता है। मूल रूप से प्रारंभिक रन एक ही मिनट के भीतर अंतराल शुरू करना है। तो init से एक सेकंड में, तुरंत हर 5 सेकंड पर दौड़ें।

var interval = 1000;
var timing =function(){
    var timer = setInterval(function(){
        console.log(interval);
        if(interval == 1000){ /*interval you dont want anymore or increment/decrement */
            interval = 3600000; /* Increment you do want for timer */
            clearInterval(timer);
            timing();
        }
    },interval);
}
timing();

वैकल्पिक रूप से यदि आप बस शुरुआत में कुछ होना चाहते थे और फिर एक विशिष्ट अंतराल पर हमेशा के लिए आप इसे सेट इन्टरवल के रूप में एक ही समय में कॉल कर सकते थे। उदाहरण के लिए:

var this = function(){
 //do
}
setInterval(function(){
  this()
},3600000)
this()

यहां हमने इसे पहली बार और फिर हर घंटे चलाया है।


3

सरल उत्तर यह है कि आप पहले से निर्मित टाइमर के अंतराल को अपडेट नहीं कर सकते । (केवल दो ही कार्य हैं setInterval/setTimerऔर clearInterval/clearTimerइसलिए, timerIdआपके पास केवल इसे निष्क्रिय कर सकते हैं।) लेकिन आप कुछ कार्यदक्ष बना सकते हैं। इस github रेपो पर एक नज़र डालें ।


2

मैं सिंक्रनाइज़ नहीं कर सका और मेरे सेटइंटरवॉल को भी बदल दिया और मैं एक प्रश्न पोस्ट करने वाला था। लेकिन मुझे लगता है कि मुझे एक रास्ता मिल गया है। यह निश्चित रूप से सुधार किया जाना चाहिए क्योंकि मैं एक शुरुआत कर रहा हूँ। तो, मैं ख़ुशी से इस बारे में आपकी टिप्पणी / टिप्पणी पढ़ूंगा।

<body onload="foo()">
<div id="count1">0</div>
<div id="count2">2nd counter is stopped</div>
<button onclick="speed0()">pause</button>
<button onclick="speedx(1)">normal speed</button>
<button onclick="speedx(2)">speed x2</button>
<button onclick="speedx(4)">speed x4</button>
<button onclick="startTimer2()">Start second timer</button>
</body>
<script>
var count1 = 0,
    count2 = 0,
    greenlight = new Boolean(0), //blocks 2nd counter
    speed = 1000,   //1second
    countingSpeed;
function foo(){
    countingSpeed = setInterval(function(){
        counter1();
        counter2();
    },speed);
}
function counter1(){
    count1++;
    document.getElementById("count1").innerHTML=count1;
}
function counter2(){
    if (greenlight != false) {
        count2++;
        document.getElementById("count2").innerHTML=count2;
    }
}
function startTimer2(){
    //while the button hasn't been clicked, greenlight boolean is false
    //thus, the 2nd timer is blocked
    greenlight = true;
    counter2();
    //counter2() is greenlighted
}

//these functions modify the speed of the counters
function speed0(){
    clearInterval(countingSpeed);
}
function speedx(a){
    clearInterval(countingSpeed);
    speed=1000/a;
    foo();
}
</script>

यदि आप चाहते हैं कि पेज लोड होने के बाद काउंटरों को बढ़ाना शुरू किया जाए, तो पहले counter1()और बाद counter2()में कॉल किया जाए। अन्यथा, यह निष्पादन से पहले मिलीसेकंड लेता है । संपादित करें: छोटा जवाबfoo()countingSpeedspeed


2
(function variableInterval() {
    //whatever needs to be done
    interval *= 2; //deal with your interval
    setTimeout(variableInterval, interval);
    //whatever needs to be done
})();

कोई छोटा नहीं हो सकता


1

मैं जावास्क्रिप्ट में एक शुरुआती हूं, और पिछले उत्तरों (लेकिन कई अच्छे विचारों) में कोई मदद नहीं मिली।
कोड का यह टुकड़ा एक्सीलरेट (त्वरण> 1) या डेक्लेरेट (त्वरण <1) से नीचे आता है। मुझे आशा है कि यह कुछ लोगों की मदद कर सकता है:

function accelerate(yourfunction, timer, refresh, acceleration) {
    var new_timer = timer / acceleration;
    var refresh_init = refresh;//save this user defined value
    if (refresh < new_timer ){//avoid reseting the interval before it has produced anything.
        refresh = new_timer + 1 ;
    };
    var lastInter = setInterval(yourfunction, new_timer);
    console.log("timer:", new_timer);
    function stopLastInter() {
        clearInterval(lastInter);
        accelerate(yourfunction, new_timer, refresh_init, acceleration);
        console.log("refresh:", refresh);
    };
    setTimeout(stopLastInter, refresh);
}

साथ में :

  • timer: setInterval एमएस में प्रारंभिक मूल्य (बढ़ते या घटते)
  • refresh: नए मूल्य से पहले के समय timerकी गणना की जाती है। यह चरणबद्ध है
  • factor: पुराने और अगले timerमूल्य के बीच का अंतर । यह कदम ऊंचाई है

1

नया कार्य करें:

// set Time interval
$("3000,18000").Multitimeout();

jQuery.fn.extend({
    Multitimeout: function () {
        var res = this.selector.split(",");
        $.each(res, function (index, val) { setTimeout(function () { 
            //...Call function
            temp();
        }, val); });
        return true;
    }
});

function temp()
{
    alert();
}

1

यहाँ एक और तरीका है एक अंतराल बनाने / तेज अंतराल टाइमर बनाने के लिए। जब तक कुल समय पार नहीं हो जाता, तब तक अंतराल एक कारक से गुणा हो जाता है।

function setChangingInterval(callback, startInterval, factor, totalTime) {
    let remainingTime = totalTime;
    let interval = startInterval;

    const internalTimer = () => {
        remainingTime -= interval ;
        interval *= factor;
        if (remainingTime >= 0) {
            setTimeout(internalTimer, interval);
            callback();
        }
    };
    internalTimer();
}

0
var counter = 15;
var interval = setTimeout(function(){
    // your interval code here
    window.counter = dynamicValue;
    interval();
}, counter);

मुझे त्रुटि दें: Uncaught TypeError: interval is not a functionलेकिन यह काम किया: jsfiddle.net/fgs5nwgn
नबी काज

0

ऊपर के आंतरिक कॉलबैक से प्रेरित होकर , मैंने मिनटों के अंश पर कॉलबैक को फायर करने के लिए एक फ़ंक्शन बनाया। यदि टाइमआउट 6 000, 15 000, 30 000, 60 000 जैसे अंतरालों पर सेट किया गया है, तो यह आपके सिस्टम घड़ी के अगले मिनट के लिए सटीक संक्रमण के सिंक में अंतराल को लगातार अनुकूल करेगा।

//Interval timer to trigger on even minute intervals
function setIntervalSynced(callback, intervalMs) {

    //Calculate time to next modulus timer event
    var betterInterval = function () {
        var d = new Date();
        var millis = (d.getMinutes() * 60 + d.getSeconds()) * 1000 + d.getMilliseconds();
        return intervalMs - millis % intervalMs;
    };

    //Internal callback
    var internalCallback = function () {
        return function () {
            setTimeout(internalCallback, betterInterval());
            callback();
        }
    }();

    //Initial call to start internal callback
    setTimeout(internalCallback, betterInterval());
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.