Skip to content

Commit c099235

Browse files
author
Matt Lee
committed
+ added support for using with promises instead of timeouts
+ removed massive comment at top of js file + prefixed all jQueryDummy properties with underscore to make collisions with jQuery properties less likely + avoided creating dummy functions for non-function properties and non-jQuery (Object.prototype) functions + if a non-number/non-promise value is passed into wait, the jQueryDummy is not created and chain execution resumes + fixed some potential edge cases where multiple 'wait' calls chained together could be broken
1 parent 988fa39 commit c099235

File tree

3 files changed

+61
-62
lines changed

3 files changed

+61
-62
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ jquery.wait allows you to easily insert a delay into a chain of jquery
77
methods. This allows you to use timeouts without uglifying your code and
88
without having to use a custom queue.
99

10+
Now with support for promises! Instead of a timeout, pass a jQuery promise into
11+
the wait method, and the chain of methods will resume calling when that promise
12+
is resolved. If the promise is rejected, the method chain will not complete.
13+
1014
example:
1115

1216
// add a class to element #foo, then remove 5 seconds later
@@ -20,6 +24,12 @@ example:
2024
// with jquery.wait
2125
$('#foo').addClass('myClass').wait(5000).removeClass('myClass');
2226

27+
// using a promise
28+
var deferred = $.Deferred();
29+
$('#foo').addClass('myClass').wait(deferred.promise()).removeClass('myClass');
30+
31+
deferred.resolve(); // removeClass will be called
32+
2333
jquery.wait will work with any default jquery object methods, as well as any
2434
methods provided by plugins loaded *before* jquery.wait.
2535

jquery.wait.js

Lines changed: 50 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,84 @@
11
/**
22
* jquery.wait - insert simple delays into your jquery method chains
3-
*
4-
* jquery.wait allows you to easily insert a delay into a chain of jquery
5-
* methods. This allows you to use timeouts without uglifying your code and
6-
* without having to use a custom queue.
7-
*
8-
* example:
9-
* // add a class to element #foo, then remove 5 seconds later
10-
*
11-
* // without jquery.wait
12-
* $('#foo').addClass('myClass');
13-
* window.setTimeout(function(){
14-
* $('#foo').removeClass('myClass');
15-
* }, 5000);
16-
*
17-
* // with jquery.wait
18-
* $('#foo').addClass('myClass').wait(5000).removeClass('myClass');
19-
*
20-
* jquery.wait will work with any default jquery object methods, as well as any
21-
* methods provided by plugins loaded *before* jquery.wait.
22-
*
23-
* !important - if you are using jquery.wait to add/remove classes that controll
24-
* css transitions, the duration of the wait needs to be slightly longer than
25-
* the transition time. So, if in the example above the class .myClass added a
26-
* 5 second transition of some sort, i would need to make the wait time longer.
27-
* I recommend 100ms longer, though your needs may vary depending on the
28-
* complexity of the animation.
29-
*
30-
* If you are chaining jQuery transitions, it is better to use the default
31-
* jquery .delay method, which has the same syntax but works with jquery queues
32-
*
333
* @author Matthew Lee [email protected]
344
*/
355

366
(function($){
7+
// fake jQuery object that allows us to resolve the entire jQuery method
8+
// chain, pause, and resume execution later.
379
function jQueryDummy($real, delay, _fncQueue){
3810
var dummy = this;
39-
this.fncQueue = (!!_fncQueue) ? _fncQueue : [];
40-
this.delayCompleted = false;
41-
this.real = $real;
11+
this._fncQueue = (typeof _fncQueue === 'undefined') ? [] : _fncQueue;
12+
this._delayCompleted = false;
13+
this._$real = $real;
4214

43-
this.timeoutKey = window.setTimeout(function(){
44-
dummy.performDummyQueueActions.call(dummy);
45-
}, delay);
15+
if (typeof delay === 'number' && delay > 0 && delay < Infinity) {
16+
// if a number between 0 and Infinity is given, set a timeout
17+
this.timeoutKey = window.setTimeout(function(){
18+
dummy._performDummyQueueActions();
19+
}, delay);
20+
} else if ((delay !== null) && (typeof delay === 'object') && (typeof delay.promise === 'function')) {
21+
// if a promise is given, use it
22+
delay.then(function () {
23+
dummy._performDummyQueueActions();
24+
});
25+
} else {
26+
// otherwise, just return the actual jQuery object and nothing will happen
27+
return $real;
28+
}
4629
}
4730

48-
jQueryDummy.prototype.addToQueue = function(fnc, arg){
49-
if (!this.delayCompleted || this.fncQueue.length > 0) {
50-
this.fncQueue.unshift({ fnc: fnc, arg: arg });
51-
}
52-
else {
53-
this.real[fnc].apply(this.real, arg);
31+
// when dummy functions are called, the name of the function and arguments are
32+
// put into a queue to execute later
33+
jQueryDummy.prototype._addToQueue = function(fnc, arg){
34+
this._fncQueue.unshift({ fnc: fnc, arg: arg });
35+
// if we've already finished the wait for some reason, just call them as
36+
// they get added
37+
if (this._delayCompleted) {
38+
return this._performDummyQueueActions();
5439
}
5540
return this;
5641
};
5742

58-
jQueryDummy.prototype.performDummyQueueActions = function(){
59-
this.delayCompleted = true;
43+
// when the delay is finished
44+
jQueryDummy.prototype._performDummyQueueActions = function(){
45+
this._delayCompleted = true;
6046

6147
var next;
62-
while (this.fncQueue.length > 0) {
63-
next = this.fncQueue.pop();
64-
// console.log('performing delayed function '+next.fnc+'('+next.arg+')');
48+
while (this._fncQueue.length > 0) {
49+
next = this._fncQueue.pop();
50+
51+
console.log(next);
52+
// if we find another `wait` call in the queue, stop dequeing and pass the
53+
// remaining queued-up function calls to that wait call
6554
if (next.fnc === 'wait') {
66-
next.arg.push(this.fncQueue);
67-
this.real[next.fnc].apply(this.real, next.arg);
68-
break;
69-
} else {
70-
this.real[next.fnc].apply(this.real, next.arg);
55+
next.arg.push(this._fncQueue);
56+
return this._$real[next.fnc].apply(this._$real, next.arg);
7157
}
58+
59+
this._$real[next.fnc].apply(this._$real, next.arg);
7260
}
73-
};
7461

62+
return this;
63+
};
7564

65+
// creates dummy object that dequeues after a times delay OR promise
7666
$.fn.wait = function(delay, _queue) {
7767
return new jQueryDummy(this, delay, _queue);
7868
};
7969

70+
//
8071
for (var fnc in $.fn) {
72+
// skip non-function properties or properties of Object.prototype
73+
if ((typeof $.fn[fnc] !== 'function') || !($.fn.hasOwnProperty(fnc))) {
74+
continue;
75+
}
76+
// create a dummy function that queues up a call
8177
jQueryDummy.prototype[fnc] = (function(fnc){
82-
8378
return function(){
8479
var arg = Array.prototype.slice.call(arguments);
85-
return this.addToQueue(fnc, arg);
80+
return this._addToQueue(fnc, arg);
8681
};
87-
8882
})(fnc);
8983
}
9084

jquery.wait.min.js

Lines changed: 1 addition & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)