Jquery interval for executing the function. Examples of the jQuery function setTimeout(). Passing parameters to setTimout

💖 Do you like it? Share the link with your friends
  • From:
  • Registered: 2014.07.08
  • Posts: 3,896
  • Likes: 497
Topic: SetTimeOut and SetInterval, which is better to use in JavaScript?

The setInterval function is designed to run code multiple times at regular intervals. However, it has a number of disadvantages, mainly different behavior in different browsers.

The first difference is the difference in the time at which the timer is set for the next launch. Let's create a small test: we will measure the amount of time that has passed since the start of the previous run and since its end.

var d1 = new Date(), d2 = new Date(); setInterval(function() ( var d = new Date(); document.body.innerHTML += (d - d1) + " " + (d - d2) + "
"; // Put a mark at the beginning of the function d1 = new Date(); while (new Date() - d1< 200); // ничего не делаем 200 миллисекунд // И в конце функции d2 = new Date(); }, 1000);

The output will be informative starting from the second line.

In Firefox, Opera, Safari and Chrome the situation will be similar: the first number will be approximately equal to 1000, the second - 200 less. The only difference will be in the spread of values. The smallest difference is in Chrome and Opera.

2 Reply by PunBB (edited by PunBB 2017.06.08 16:45)
  • From: Moscow, Sovkhoznay 3, apt. 98
  • Registered: 2014.07.08
  • Posts: 3,896
  • Likes: 497

Another difference that is less noticeable and more difficult to reproduce, but can sometimes cause a lot of trouble, is resistance to system time changes. If you run the following test

setInterval(function() ( document.body.innerHTML = Math.random(); ), 500);

And after starting, set the system time back a minute, then in the Firefox and Safari browsers the change of numbers will pause, and after a minute it will start again. Of course, manual translation of system time is an extremely rare situation, but many systems are configured to automatically synchronize time with servers on the Internet, so in some situations this factor cannot be discounted.

Another small disadvantage of the setInterval function is that in order to be able to stop its action, you need to remember its identifier somewhere, which is not always convenient.

3 Reply by PunBB
  • From: Moscow, Sovkhoznay 3, apt. 98
  • Registered: 2014.07.08
  • Posts: 3,896
  • Likes: 497
Re: SetTimeOut and SetInterval, which is better to use in JavaScript?

To get rid of the listed disadvantages of setInterval, you can use multiple setTimeout.

An important alternative to setInterval is the recursive setTimeout:

/** instead of: var timerId = setInterval(function() ( alert("tick"); ), 2000); */ var timerId = setTimeout(function tick() ( alert("tick"); timerId = setTimeout(tick, 2000); ), 2000);

In the code above, the next execution is scheduled immediately after the previous one finishes.

Recursive setTimeout is a more flexible timing method than setInterval, since the time until the next execution can be scheduled differently, depending on the results of the current one.

For example, we have a service that polls the server for new data every 5 seconds. If the server is overloaded, you can increase the polling interval to 10, 20, 60 seconds... And then return it back when everything returns to normal.

If we regularly run CPU-intensive tasks, then we can estimate the time spent on their execution and plan the next run earlier or later.

4 Reply by PunBB
  • From: Moscow, Sovkhoznay 3, apt. 98
  • Registered: 2014.07.08
  • Posts: 3,896
  • Likes: 497
Re: SetTimeOut and SetInterval, which is better to use in JavaScript?

Recursive setTimeout guarantees a pause between calls, setInterval does not.

Let's compare the two codes. The first one uses setInterval:

var i = 1; setInterval(function() ( func(i); ), 100);

The second one uses a recursive setTimeout:

var i = 1; setTimeout(function run() ( func(i); setTimeout(run, 100); ), 100);

With setInterval, the internal timer will fire exactly every 100 ms and call func(i):

The real pause between func calls with setInterval is less than indicated in the code!

This is natural, because the operating time of the function is not taken into account in any way; it “eats up” part of the interval.

It is also possible that func turned out to be more complex than we expected and took longer than 100 ms to execute.

In this case, the interpreter will wait for the function to complete, then check the timer and, if the time for calling setInterval has already come (or passed), then the next call will occur immediately.

If the function runs longer than the setInterval pause, then calls will occur without any interruption at all.

5 Reply by sempai
  • From: Jerusalem
  • Registered: 2015.06.02
  • Posts: 958
  • Likes: 274
Re: SetTimeOut and SetInterval, which is better to use in JavaScript?

It all depends on the task at hand. Initially, SetTimeOut is used to start the timer once, and SetInterval is used to start a loop. But both functions can be used to run scripts cyclically; if, for example, you run them recursively in the SetTimeOut function, then they will act almost similarly to SetInterval.

The disadvantage of SetInterval at the moment is that it does not take into account the execution time of the script (function) itself, and if, for example, you use it for heavy queries, then the interval time will be significantly reduced, and it may differ in different browsers.

But again, if the function or request is minimized, then the end user is unlikely to feel the difference.
Therefore, what to use is up to everyone to decide for themselves.

It is extremely important to understand how they work JavaScript timers. Often their behavior does not match our intuitive understanding of multithreading, and this is due to the fact that in reality they are executed in a single thread. Let's look at four functions with which we can manage timers:

  • var id = setTimeout(fn, delay); - Creates a simple timer that will call a given function after a given delay. The function returns a unique ID with which the timer can be paused.
  • var id = setInterval(fn, delay); - Similar to setTimeout, but continuously calls the function at a specified interval (until stopped).
  • clearInterval(id);, clearTimeout(id); - Accepts a timer ID (returned by one of the functions described above) and stops execution of callback"a.
The main idea to consider is that the accuracy of the timer delay period is not guaranteed. To begin with, the browser executes all asynchronous JavaScript events in one thread (such as mouse clicks or timers) and only at the time when it is the turn of that event. This is best demonstrated by the following diagram:

There's quite a lot of information to take in in this figure, but understanding it will give you a deeper understanding of how JavaScript asynchrony works. This chart represents time vertically in milliseconds, the blue blocks show blocks of JavaScript code that were executed. For example, the first block is executed on average in 18ms, a mouse click blocks execution for about 11ms, etc.

JavaScript can only execute one chunk of code (due to the single-threaded nature of execution), each of which blocks the execution of other asynchronous events. This means that when an asynchronous event occurs (such as a mouse click, a timer call, or the completion of an XMLHttp request), it is added to a queue and executed later (implementation varies by browser, of course, but let's agree to call it a "queue") .

To begin with, let’s imagine that two timers start inside a JavaScript block: setTimeout with a delay of 10ms and setInterval with the same delay. Depending on when the timer starts, it will fire at the moment when we have not yet completed the first block of code. Note, however, that it does not fire immediately (this is not possible due to single threading). Instead, the deferred function is queued and executed at the next available moment.

Also, during the execution of the first JavaScript block, a mouse click occurs. The handler for this asynchronous event (and it is asynchronous because we cannot predict it) cannot be executed directly at this moment, so it also ends up in a queue, like the timer.

After the first block of JavaScript code has been executed, the browser asks the question, “What is waiting to be executed?” In this case, the mouse click handler and timer are in a waiting state. The browser selects one of them (the click handler) and executes it. The timer will wait for the next available chunk of time in the execution queue.

Note that while the mouse click handler is executing, the first interval-callback fires. Just like timer-callback, it will be queued. However, note that when interval fires again (while the timer-callback is running), it will be removed from the queue. If every interval-callback" were queued while a large piece of code was executing, it would result in a bunch of functions waiting to be called, with no delay periods between them finishing their execution. Instead, browsers tend to wait until there are no more functions left. in the queue before adding another one to the queue.

Thus, we can observe the case when the third firing of the interval-callback coincides with the moment when it is already executed. This illustrates an important point: intervals don't care what is currently running, they will be added to the queue without regard to the delay period between executions.

Finally, after the second interval-callback completes, we will see that there is nothing left for the JavaScript engine to execute. This means that the browser again waits for new asynchronous events to appear. This will happen at the 50ms mark, where interval-callback will work again. At this point there will be nothing to block it, so it will work immediately.

Let's look at an example that nicely illustrates the difference between setTimeout and setInterval.
setTimeout(function())( /* Some long block of code... */ setTimeout(arguments.callee, 10); ), 10); setInterval(function())( /* Some long block of code... */ ), 10);
These two options are equivalent at first glance, but in reality they are not. Code using setTimeout will always have a delay of at least 10ms after the previous call (it can be more, but never less), while code using setInterval will tend to be called every 10ms, regardless of when the previous call occurred.

Let's summarize everything said above:
- JavaScript engines use a single-threaded environment, transforming asynchronous events into a queue awaiting execution,
- The setTimeout and setInterval functions are executed fundamentally differently in asynchronous code,
- If the timer cannot be executed in this moment, it will be delayed until the next execution point (which will be longer than the desired delay),
- Intervals (setInterval) can be executed one after another without delay if their execution takes longer than the specified delay.

All this is extremely important information for development. Knowing how the JavaScript engine works, especially with a lot of asynchronous events (which often happens), lays a great foundation for building advanced applications.

The setInterval() method, offered on the Window and Worker interfaces, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. It returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval() . This method is defined by the WindowOrWorkerGlobalScope mixin.

Syntax var intervalID = scope.setInterval( func, delay, [arg1, arg2, ...]); var intervalID = scope.setInterval( code, delay); Parameters func A function to be executed every delay milliseconds. The function is not passed any arguments, and no return value is expected. code An optional syntax allows you to include a string instead of a function, which is compiled and executed every delay milliseconds. This syntax is not recommended for the same reasons that make using eval() a security risk. delay The time, in milliseconds (thousandths of a second), the timer should delay in between executions of the specified function or code. See below for details on the permitted range of delay values. arg1, ..., argN Optional Additional arguments which are passed through to the function specified by func once the timer expires.

Note : Passing additional arguments to setInterval() in the first syntax does not work in Internet Explorer 9 and earlier. If you want to enable this functionality on that browser, you must use a polyfill (see the section).

Return value

The returned intervalID is a numeric, non-zero value which identifies the timer created by the call to setInterval() ; this value can be passed to cancel the timeout.

It may be helpful to be aware that setInterval() and setTimeout() share the same pool of IDs, and that clearInterval() and clearTimeout() can technically be used interchangeably. For clarity, however, you should try to always match them to avoid confusion when maintaining your code.

Note: The delay argument is converted to a signed 32-bit integer. This effectively limits delay to 2147483647 ms, since it"s specified as a signed integer in the IDL.

Examples Example 1: Basic syntax

The following example demonstrates setInterval() "s basic syntax.

Var intervalID = window.setInterval(myCallback, 500, "Parameter 1", "Parameter 2"); function myCallback(a, b) ( // Your code here // Parameters are purely optional. console.log(a); console.log(b); )

Example 2: Alternating two colors

The following example calls the flashtext() function once a second until the Stop button is pressed.

setInterval/clearInterval example var nIntervId; function changeColor() ( nIntervId = setInterval(flashText, 1000); ) function flashText() ( var oElem = document.getElementById("my_box"); oElem.style.color = oElem.style.color == "red" ? " blue" : "red"; // oElem.style.color == "red" ? "blue" : "red" is a ternary operator. ) function stopTextColor() ( clearInterval(nIntervId); )

Hello World

Stop

Example 3: Typewriter simulation

The following example simulates typewriter by first clearing and then slowly typing content into the NodeList that matches a specified group of selectors.

JavaScript Typewriter - MDN Example function Typewriter (sSelector, nRate) ( function clean () ( clearInterval(nIntervId); bTyping = false; bStart = true; oCurrent = null; aSheets.length = nIdx = 0; ) function scroll (oSheet, nPos , bEraseAndStop) ( if (!oSheet.hasOwnProperty("parts") || aMap.length< nPos) { return true; } var oRel, bExit = false; if (aMap.length === nPos) { aMap.push(0); } while (aMap < oSheet.parts.length) { oRel = oSheet.parts]; scroll(oRel, nPos + 1, bEraseAndStop) ? aMap++ : bExit = true; if (bEraseAndStop && (oRel.ref.nodeType - 1 | 1) === 3 && oRel.ref.nodeValue) { bExit = true; oCurrent = oRel.ref; sPart = oCurrent.nodeValue; oCurrent.nodeValue = ""; } oSheet.ref.appendChild(oRel.ref); if (bExit) { return false; } } aMap.length--; return true; } function typewrite () { if (sPart.length === 0 && scroll(aSheets, 0, true) && nIdx++ === aSheets.length - 1) { clean(); return; } oCurrent.nodeValue += sPart.charAt(0); sPart = sPart.slice(1); } function Sheet (oNode) { this.ref = oNode; if (!oNode.hasChildNodes()) { return; } this.parts = Array.prototype.slice.call(oNode.childNodes); for (var nChild = 0; nChild < this.parts.length; nChild++) { oNode.removeChild(this.parts); this.parts = new Sheet(this.parts); } } var nIntervId, oCurrent = null, bTyping = false, bStart = true, nIdx = 0, sPart = "", aSheets = , aMap = ; this.rate = nRate || 100; this.play = function () { if (bTyping) { return; } if (bStart) { var aItems = document.querySelectorAll(sSelector); if (aItems.length === 0) { return; } for (var nItem = 0; nItem < aItems.length; nItem++) { aSheets.push(new Sheet(aItems)); /* Uncomment the following line if you have previously hidden your elements via CSS: */ // aItems.style.visibility = "visible"; } bStart = false; } nIntervId = setInterval(typewrite, this.rate); bTyping = true; }; this.pause = function () { clearInterval(nIntervId); bTyping = false; }; this.terminate = function () { oCurrent.nodeValue += sPart; sPart = ""; for (nIdx; nIdx < aSheets.length; scroll(aSheets, 0, false)); clean(); }; } /* usage: */ var oTWExample1 = new Typewriter(/* elements: */ "#article, h1, #info, #copyleft", /* frame rate (optional): */ 15); /* default frame rate is 100: */ var oTWExample2 = new Typewriter("#controls"); /* you can also change the frame rate value modifying the "rate" property; for example: */ // oTWExample2.rate = 150; onload = function () { oTWExample1.play(); oTWExample2.play(); }; span.intLink, a, a:visited { cursor: pointer; color: #000000; text-decoration: underline; } #info { width: 180px; height: 150px; float: right; background-color: #eeeeff; padding: 4px; overflow: auto; font-size: 12px; margin: 4px; border-radius: 5px; /* visibility: hidden; */ }

CopyLeft 2012 by Mozilla Developer Network

[ Play | Pause | Terminate]

Vivamus blandit massa ut metus mattis in fringilla lectus imperdiet. Proin ac ante a felis ornare vehicula. Fusce pellentesque lacus vitae eros convallis ut mollis magna pellentesque. Pellentesque placerat enim at lacus ultricies vitae facilisis nisi fringilla. In tincidunt tincidunt tincidunt. JavaScript Typewriter

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ultrices dolor ac dolor imperdiet ullamcorper. Suspendisse quam libero, luctus auctor mollis sed, malesuada condimentum magna. Quisque in ante tellus, in placerat est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec a mi magna, quis mattis dolor. Etiam sit amet ligula quis urna auctor imperdiet nec faucibus ante. Mauris vel consectetur dolor. Nunc eget elit eget velit pulvinar fringilla consectetur aliquam purus. Curabitur convallis, justo posuere porta egestas, velit erat ornare tortor, non viverra justo diam eget arcu. Phasellus adipiscing fermentum nibh ac commodo. Nam turpis nunc, suscipit a hendrerit vitae, volutpat non ipsum.

Phasellus ac nisl lorem:
Nullam commodo suscipit lacus non aliquet. Phasellus ac nisl lorem, sed facilisis ligula. Nam cursus lobortis placerat. Sed dui nisi, elementum eu sodales ac, placerat sit amet mauris. Pellentesque dapibus tellus ut ipsum aliquam eu auctor dui vehicula. Quisque ultrices laoreet erat, at ultrices tortor sodales non. Sed venenatis luctus magna, ultricies ultricies nunc fringilla eget. Praesent scelerisque urna vitae nibh tristique varius consequat neque luctus. Integer ornare, erat a porta tempus, velit justo fermentum elit, a fermentum metus nisi eu ipsum. Vivamus eget augue vel dui viverra adipiscing congue ut massa. Praesent vitae eros erat, pulvinar laoreet magna. Maecenas vestibulum mollis nunc in posuere. Pellentesque sit amet metus a turpis lobortis tempor eu vel tortor. Cras sodales eleifend interdum.

Duis lobortis sapien quis nisl luctus porttitor. In tempor semper libero, eu tincidunt dolor eleifend sit amet. Ut nec velit in dolor tincidunt rhoncus non non diam. Morbi auctor ornare orci, non euismod felis gravida nec. Curabitur elementum nisi a eros rutrum nec blandit diam placerat. Aenean tincidunt risus ut nisi consectetur cursus. Ut vitae quam elit. Donec dignissim est in quam tempor consequat. Aliquam aliquam diam non felis convallis suscipit. Nulla facilisi. Donec lacus risus, dignissim et fringilla et, egestas vel eros. Duis malesuada accumsan dui, at fringilla mauris bibStartum quis. Cras adipiscing ultricies fermentum. Praesent bibStartum condimentum feugiat.

Nam faucibus, ligula eu fringilla pulvinar, lectus tellus iaculis nunc, vitae scelerisque metus leo non metus. Proin mattis lobortis lobortis. Quisque accumsan faucibus erat, vel varius tortor ultricies ac. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec libero nunc. Nullam tortor nunc, elementum a consectetur et, ultrices eu orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque a nisl eu sem vehicula egestas.

Callback arguments

As previously discussed, Internet Explorer versions 9 and below do not support the passing of arguments to the callback function in either setTimeout() or setInterval() . The following IE-specific code demonstrates a method for overcoming this limitation. To use, simply add the following code to the top of your script.

/*\ |*| |*| IE-specific polyfill that enables the passage of arbitrary arguments to the |*| callback functions of javascript timers (HTML5 standard syntax)..setInterval |*| https://site/User:fusionchess |*| |*| Syntax: |*| var timeoutID = window.setTimeout(func, delay[, arg1, arg2, ...]); |*| var timeoutID = window.setTimeout(code, delay); |*| var intervalID = window.setInterval(func, delay[, arg1, arg2, ...]); |*| var intervalID = window.setInterval(code, delay); |*| \*/ if (document.all && !window.setTimeout.isPolyfill) ( var __nativeST__ = window.setTimeout; window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var aArgs = Array .prototype.slice.call(arguments, 2); return __nativeST__(vCallback instanceof Function ? function () ( vCallback.apply(null, aArgs); ) : vCallback, nDelay); ); window.setTimeout.isPolyfill = true; ) if (document.all && !window.setInterval.isPolyfill) ( var __nativeSI__ = window.setInterval; window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var aArgs = Array.prototype. slice.call(arguments, 2); return __nativeSI__(vCallback instanceof Function ? function () ( vCallback.apply(null, aArgs); ) : vCallback, nDelay); ); window.setInterval.isPolyfill = true; )

Another possibility is to use an anonymous function to call your callback, although this solution is a bit more expensive. Example:

Var intervalID = setInterval(function() ( myFunc("one", "two", "three"); ), 1000); var intervalID = setInterval(function(arg1) ().bind(undefined, 10), 1000);

Inactive tabs Requires Gecko 5.0(Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)

Starting in Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), intervals are clamped to fire no more often than once per second in inactive tabs.

The "this" problem

When you pass a method to setInterval() or any other function, it is invoked with the wrong this value. This problem is explained in detail in the JavaScript reference.

Explanation

Code executed by setInterval() runs in a separate execution context than the function from which it was called. As a consequence, the this keyword for the called function is set to the window (or global) object, it is not the same as the this value for the function that called setTimeout . See the following example (which uses setTimeout() instead of setInterval() – the problem, in fact, is the same for both timers):

MyArray = ["zero", "one", "two"]; myArray.myMethod = function (sProperty) ( alert(arguments.length > 0 ? this : this); ); myArray.myMethod(); // prints "zero,one,two" myArray.myMethod(1); // prints "one" setTimeout(myArray.myMethod, 1000); // prints "" after 1 second setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1.5 seconds // passing the "this" object with .call won"t work // because this will change the value of this inside setTimeout itself // while we want to change the value of this inside myArray.myMethod // in fact, it will be an error because setTimeout code expects this to be the window object: setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object" setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error

As you can see there are no ways to pass the this object to the callback function in the legacy JavaScript.

A possible solution

A possible way to solve the "this" problem is to replace the two native setTimeout() or setInterval() global functions with two non-native ones that enable their invocation through the Function.prototype.call method. The following example shows a possible replacement:

// Enable the passage of the "this" object through the JavaScript timers var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval; window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeST__(vCallback instanceof Function ? function () ( vCallback.apply(oThis, aArgs); ) : vCallback, nDelay); ); window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) ( var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeSI__(vCallback instanceof Function ? function () ( vCallback.apply(oThis, aArgs); ) : vCallback, nDelay); );

These two replacements also enable the HTML5 standard passage of arbitrary arguments to the callback functions of timers in IE. So they can be used as non-standard-compliant polyfills also. See the for a standard-compliant polyfill

New feature test:

MyArray = ["zero", "one", "two"]; myArray.myMethod = function (sProperty) ( alert(arguments.length > 0 ? this : this); ); setTimeout(alert, 1500, "Hello world!"); // the standard use of setTimeout and setInterval is preserved, but... setTimeout.call(myArray, myArray.myMethod, 2000); // prints "zero,one,two" after 2 seconds setTimeout.call(myArray, myArray.myMethod, 2500, 2); // prints "two" after 2.5 seconds

For a more complex but still modular version of it ( Daemon) see JavaScript Daemons Management . This more complex version is nothing but a large and scalable collection of methods for the Daemon constructor. However, the Daemon constructor itself is nothing but a clone of MiniDaemon with an added support for init and onstart functions declared during the instantiation of the daemon. So the MiniDaemon framework remains the recommended way for simple animations , because Daemon without its collection of methods is essentially a clone of it.

minidaemon.js /*\ |*| |*| :: MiniDaemon:: |*| |*| Revision #2 - September 26, 2014.setInterval |*| https://site/User:fusionchess |*| https://github.com/madmurphy/minidaemon.js |*| |*| This framework is released under the GNU Lesser General Public License, version 3 or later. |*| http://www.gnu.org/licenses/lgpl-3.0.html |*| \*/ function MiniDaemon (oOwner, fTask, nRate, nLen) ( if (!(this && this instanceof MiniDaemon)) ( return; ) if (arguments.length< 2) { throw new TypeError("MiniDaemon - not enough arguments"); ) if (oOwner) ( this.owner = oOwner; ) this.task = fTask; if (isFinite(nRate) && nRate > 0) ( this.rate = Math.floor(nRate); ) if (nLen > 0) ( this.length = Math.floor(nLen); ) ) MiniDaemon.prototype.owner = null; MiniDaemon.prototype.task = null; MiniDaemon.prototype.rate = 100; MiniDaemon.prototype.length = Infinity; / * These properties should be read-only */ MiniDaemon.prototype.SESSION = -1; MiniDaemon.prototype.INDEX = 0; MiniDaemon.prototype.PAUSED = true; MiniDaemon.prototype.BACKW = true; /* Global methods */ MiniDaemon .forceCall = function (oDmn) ( oDmn.INDEX += oDmn.BACKW ? -1: 1; if (oDmn.task.call(oDmn.owner, oDmn.INDEX, oDmn.length, oDmn.BACKW) === false || oDmn.isAtEnd()) ( oDmn.pause(); return false; ) return true; ); /* Instances methods */ MiniDaemon.prototype.isAtEnd = function () ( return this.BACKW ? isFinite(this.length ) && this.INDEX< 1: this.INDEX + 1 >this.length; ); MiniDaemon.prototype.synchronize = function () ( if (this.PAUSED) ( return; ) clearInterval(this.SESSION); this.SESSION = setInterval(MiniDaemon.forceCall, this.rate, this); ); MiniDaemon.prototype.pause = function () ( clearInterval(this.SESSION); this.PAUSED = true; ); MiniDaemon.prototype.start = function (bReverse) ( var bBackw = Boolean(bReverse); if (this.BACKW === bBackw && (this.isAtEnd() || !this.PAUSED)) ( return; ) this.BACKW = bBackw; this.PAUSED = false; this.synchronize(); );

MiniDaemon passes arguments to the callback function. If you want to work on it with browsers that natively do not support this feature, use one of the methods proposed above.

Syntax

var myDaemon = new MiniDaemon( thisObject, callback[ , rate [, length]]);

Description Usage notes

The setInterval() function is commonly used to set a delay for functions that are executed again and again, such as animations. You can cancel the interval using WindowOrWorkerGlobalScope.clearInterval() .

If you wish to have your function called once after the specified delay, use .

Delay restrictions

It"s possible for intervals to be nested; that is, the callback for setInterval() can in turn call setInterval() to start another interval running, even though the first one is still going. To mitigate the potential impact this can have on performance, once intervals are nested beyond five levels deep, the browser will automatically enforce a 4 ms minimum value for the interval. Attempts to specify a value less than 4 ms in deeply-nested calls to setInterval() will be pinned to 4 ms.

Browsers may enforce even more stringent minimum values ​​for the interval under some circumstances, although these should not be common. Note also that the actual amount of time that elapses between calls to the callback may be longer than the given delay; see Reasons for delays longer than specified in WindowOrWorkerGlobalScope.setTimeout() for examples.

Ensure that execution duration is shorter than interval frequency

If there is a possibility that your logic could take longer to execute than the interval time, it is recommended that you recursively call a named function using setTimeout() . For example, if using setInterval() to poll a remote server every 5 seconds, network latency, an unresponsive server, and a host of other issues could prevent the request from completing in its allotted time. As such, you may find yourself with queued up XHR requests that won"t necessarily return in order.

In programming in scripting languages, there is periodically a need to create a pause - to pause the execution of the program for a while, and then continue working. For example, in VBS and PHP scripts the following methods are possible:

VBS: wscript.sleep 1500 (stop for 1.5 seconds)

PHP: sleep(10); (stop for 10 seconds)

During such pauses, the runtime system (PHP or VBS) doing nothing. A developer trying to intuitively use something similar in Javascript will be unpleasantly surprised. Common mistake when trying to create a pause in Javascript it looks like this:

Function badtest() ( for (var i=1; i< 10; i++) { window.setTimeout("document.getElementById("test1").value += " + i, 900) } }

You think that when, during the loop, the turn comes to drawing the next number, your setTimeout will honestly stop the Javascript from working, wait 0.9 seconds, add the desired number to the end of the input field and then continue working. But in reality this is not true: setInterval and setTimeout in Javascript only delay the execution of the action (or function) specified in parentheses. In our example, the following will happen:

  • i = 1;
  • delay adding the number "1" to the input field by 0.9 seconds;
  • Immediately after setting this problem, the cycle continues: i=2;
  • delay adding the number "2" to the input field by 0.9 seconds;
  • Immediately means, for example, 1 ms (that is, disproportionately small compared to 900 ms): the loop will do its work almost instantly, creating several deferred tasks from the same point in time. This means that all pending “drawing” tasks will be completed at almost the same time, without pauses between adding new numbers. The cycle starts; everything freezes for 0.9 s; and shirr - all the numbers are shot in a row one after another.

    How to correctly apply setTimeout in such a case? It's complicated. You'll have to call the function recursively(from within the function the same function), and so that this process is not endless, set a stopping condition (for example, the size of the number to be printed):

    Function welltest() ( if (i< 9) { document.getElementById("test2").value += ++i window.setTimeout("welltest()", 400) } }

    And the variable i will have to be initialized outside the function - for example, like this:

    Now everything works as it should (we reduced the delay time from 0.9 s to 0.4 s). But for such tasks, it is more logical to use setInterval rather than setTimeout (although this will require two functions):

    Function besttest() ( window.i = 0 window.timer1 = window.setInterval("draw()", 400) ) function draw() ( document.getElementById("test3").value += ++i if (i >= 9) clearInterval(window.timer1) )

    The peculiarity of the Javascirpt setInterval method is that it does not pass “by itself”; it must be stopped with a special clearInterval method. And to make it clear what exactly to stop, the task for the deferred action is assigned a special identifier - a timer: window.timer1 = window.setInterval(...) .

    Identifiers can also be assigned to tasks created by the setTimeout method. All timer IDs must be distinct from each other (unique within the current browser window). Then you can create several different tasks in the window that use deferred actions, and these tasks will be executed in parallel (sort of simultaneously, if the computer has enough resources), which is basically impossible in PHP or VBS.

    Here is an example of a page with several Javascript timers running simultaneously: setinterval.htm(Javascript functions in file setinterval.js). All page timers (except menu) can be stopped using the Esc key. All example timers are based on a “natural” (and not abstract i++) countdown - time or distance. All “clocks” are specially desynchronized (for clarity). Distance-dependent timers are used in the “indicator” and in the drop-down (“pull-out”) menu.

    Drop-down menu

    Our sliding menu is actually sliding (from under the “header”): gaps are specially left between the elements so that you can see how it slides out. Unexpectedly, it turned out that we could not make the exit equally smooth for lists of different lengths - probably due to the low performance of the computer (AMD Athlon 999 MHz).

    It is quite obvious that for beauty and harmony it is necessary that the lists of different menu items appear at the same time. That is, longer lists should drop out with more high speed, shorter ones - at a lower speed. It would seem that it could be implemented like this:

  • We set the total “departure” time, for example, to 200 ms.
  • If the dropdown list has a height of 20 px, it is obvious that we can move it down one pixel per 10 ms interval - and then in 200 ms the entire list will come out.
  • If the dropdown is 40px high, to fit in the same amount of time we have to move it down one pixel every 5ms.
  • By this logic, if the dropdown list is 200px high, we should move it down one pixel every 1ms. But such speed does not work on our computer - the browser simply does not have time to draw the new position of the list in one millisecond. Yes. Javascript manages to count (what is there to count?), but the browser (Firefox) does not have time to display. Typical situation for the web.

    Therefore, it is possible to more or less equalize the menu departure time only with the help of crutches, and it is still unclear how this will work for more fast computer. But we should count on the slowest one, right? The algorithm (without taking into account the speed of the computer) turns out something like this:

  • Set the total time for checking out the list: time = 224 (ms).
  • We set the minimum time for one interval in the cycle: delay = 3 (ms).
  • Set the minimum step for moving the list: offset = 1 (px).
  • We change all this depending on the height of the list: 1) increase the delay (interval) time in inverse proportion to the height and directly proportional to the total time time (at a height of 224 the coefficient is 1); 2) if the height is greater than 40 px, increase the minimum step in proportion to the height. The constant "40" was obtained experimentally for the slowest computer. Tests on a Pentium 4 CPU 2.53GHz computer revealed exactly the same number - 40. Otherwise, timers go out of order, lists go out of step.
  • Now the lists are more or less coming out. For more or less similar time. On the page setinterval.htm.

    And here comes Bruce:

    Function slide_do(obj, maxtop, offset) ( if (getTopLeft(obj).top< maxtop) { obj.style.top = getTopLeft(obj).top + offset } else { if (obj && obj.timer1) { clearInterval(obj.timer1) obj.timer1 = null } } }

    The function itself, which pushes nested lists out of the menu, is, as we can see, very simple. All that remains is to run it with something like this line:

    Ts.timer1 = setInterval(function())(slide_do(ts, maxtop, offset)), delay)

    Well, before starting, just calculate all these maxtop and offset, and also place the list in the mintop position. This is what the “preliminary” slide() function of 40 lines does. And all together - in a file setinterval.js. Yes, and this crap won't work at all without the included styles file



    tell friends