Can jQuery be used as a sleep() or wait() function? Suspending the execution of the statements after the wait. I tried $().delay(5000) but there was no 5 second wait. Is delay() only used in effects?
I am not looking for solutions which involve setTimeout delayed execution of another function or a CPU hogging solution. I want a sleep() function which can be reused in different scripts.
Addition:
I didn't mean to suggest a solution which doesn't use setTimeout at all. I have seen solutions which required to move all code after where the delay is needed into its own function so that setTimeout can call it. I don't want that. Either a self contained wrapper function for using setTimeout or use jQuery delay() in a dummy non visual effect just for the purpose of simulating a sleep function.
Can jQuery be used as a sleep() or wait() function? Suspending the execution of the statements after the wait. I tried $().delay(5000) but there was no 5 second wait. Is delay() only used in effects?
I am not looking for solutions which involve setTimeout delayed execution of another function or a CPU hogging solution. I want a sleep() function which can be reused in different scripts.
Addition:
I didn't mean to suggest a solution which doesn't use setTimeout at all. I have seen solutions which required to move all code after where the delay is needed into its own function so that setTimeout can call it. I don't want that. Either a self contained wrapper function for using setTimeout or use jQuery delay() in a dummy non visual effect just for the purpose of simulating a sleep function.
Share Improve this question edited Jul 30, 2010 at 23:20 Tony_Henrich asked Jul 30, 2010 at 22:57 Tony_HenrichTony_Henrich 44.3k80 gold badges252 silver badges390 bronze badges5 Answers
Reset to default 4You're going to be out of luck. Any sleep()
function will most likely need to utilize setTimeout
(or possibly setInterval
). In fact, delay()
itself uses setTimeout
. From jQuery 1.4.2 source:
delay: function( time, type ) {
time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
type = type || "fx";
return this.queue( type, function() {
var elem = this;
setTimeout(function() {
jQuery.dequeue( elem, type );
}, time );
});
},
.delay()
only works with queues, which the effects use (the fx
queue). It is possible to use custom queues using .queue()
This works wonderfully to me:
http://benalman./projects/jquery-dotimeout-plugin/
$.doTimeout(3000,function(){
alert('yahoooooo!');
});
Examples:
http://benalman./code/projects/jquery-dotimeout/examples/delay-poll/
Javascript (and by extension, jQuery) doesn't have a real "sleep" function. You can more or less abuse setTimeout & setInterval (and their derivatives, like delay) to simulate sleep, but you're usually better off just adapting to the setInterval/Timeout way of doing things... figure out what you want done, seal it off in a function, pass it as an argument to one of those two.
Edit:
Okay, I see your edit. You really want a conventional sleep function. What follows is absolutely an abuse and not at all what I'd remend. But if I had to build one to save my life, here's how I'd do it: test how long a high number of loop cycles takes, do a statistically significant number of these tests, average the results, and use that information to define a function that roughly translates a given number of milliseconds into a number of loop cycles, which it then runs through.
In JavaScript:
function timeloop(cycles) {
var start = new Date().getTime();
for(var j=0; j<cycles; j++);
var end = new Date().getTime();
return end-start;
}
var sleep = (function () {
var ms_tally = 0, i, s = 100, L = 10000;
for(i=0; i<s; i++)
ms_tally += timeloop(L);
var avg = ms_tally / i;
var ms_per_cycle = avg / L;
var cycles_per_ms = 1 / ms_per_cycle;
return eval('function (ms) { for(var k=0, z=ms*'+cycles_per_ms+'; k<z; k++); }');
})()
I wouldn't trust my life, health, or even $20 to the accuracy of the timing, though. If you need any degree of precision finer than half a second, the right way to do this in JavaScript is to trust the facilities built into whatever environment you're using... and in the browser, that's setInterval and setTimeout.
Edit #2:
I see the remendation for Ben Alman's doTimeout plugin in one of the ments. After looking it over, it's worth noting that it is a better idea than the abomination I have produced above in just about every way. It isn't quite the fortable sleep
-y syntax we're often used to, and you still have to think about your code in functions in some marginal way, but at least you can still keep the sequential feel. If you can't bring yourself to use setTimeout/Interval directly, use doTimeout or something like it.
You are going to have to use setTimeout
or similar in some way if you don't want to chew CPU time.
Here's an example:
function myfn() {
// make it so that `myvar` is in scope and can
// be shared by both `fn1` and `fn2`
var myvar
function fn1() {
alert('foo')
// set `bar` in the above `myfn`'s scope (without `var`)
myvar = 'bar'
// sleep for 1.2 seconds
setTimeout(fn2, 1200)
}
function fn2() {
alert(myvar)
}
fn1()
}
myfn()
According to your question How to use jQuery's delay() as a sleep()? , and to answer this:
I tried $().delay(5000) but there was no 5 second wait. Is delay() only used in effects?
Have you already tried jQuery.queue() with delay()? for e.g.
$.fn.extend({
changeBgColor: function(color) {
return this.each(function() {
$(this).css("background-color", color);
});
}
});
$.fn.wait = function(mls, callback) {
return this.delay(mls).queue(function () {
$("span").text($(this).queue().length);
callback();
$(this).dequeue();
});
};
$(document).ready(function(){
$("#start").click(function(){
var div = $("div");
div.delay(1000).queue(function () {
$("span").text(div.queue().length);
div.css("background-color", "red").text("red");
$(this).dequeue();
}).delay(1000).queue(function (next) {
$("span").text(div.queue().length);
div.changeBgColor("green").text("green");
next();
});
div.wait(1000,function () {
div.changeBgColor("yellow").text("yellow");
}).wait(1000,function () {
div.changeBgColor("blue").text("blue");
});
});
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis./ajax/libs/jquery/3.2.0/jquery.min.js"></script>
</head>
<body>
<p><button id="start">Start</button> <span></span></p>
<div style="display:inline-block;background:blue;height:100px;width:100px;"></div>
<div style="display:inline-block;background:blue;height:100px;width:100px;"></div>
</body>
</html>
The queue() method allows you to create a queue of functions to be executed on selected elements. The dequeue() method executes them in order.