This is probably a simple question, but i'm totally lost.
I have this function.
m.util.genericSwipeVertFunc = function (
ajaxRequest,
swipeOutTarget,
swipeInTarget
) {
var stage1, stage2, failStage, dfd = $.Deferred(), finalStage, functionPromise;
// Swipe of screen wait for ajax request
stage1 = function () {
return $.when(
ajaxRequest, // Returns $.Deferred()
m.util.animateDeffered(swipeOutTarget, "fadeOutDown", true) // Returns $.Deferred()
);
};
// Swipe and Show
stage2 = function () {
swipeInTarget.show();
return m.util.animateDeffered(swipeInTarget, "fadeInDown"); // Returns $.Deferred()
};
finalStage = function () {
dfd.resolve();
}
failStage = function () {
console.log("fail!");
swipeInTarget.hide();
};
functionPromise = stage1()
.then(stage2)
.then(finalStage);
$.when(functionPromise,dfd)
.fail(failStage);
return dfd;
};
Basically it does some fancy animations to fade in and out different response outputs from ajax functions. This all works fine, except when the user tries to change between targets very fast(before one chain finishes they start another) I get crazy animation all over the place.
I want to be able to reject the chain at any point by doing something like this.
// called on script load.
var currentAction = $.Deferred();
// Called everytime someone starts animation chain.
currentAction.reject();
currentAction = m.util.genericSwipeVertFunc(dfd, swipeOutTarget, swipeInTarget);
);
With my current code the failFunction is hit correctly but it doesn't stop the execution of stage2. So it hides then shows it and continues breaking things.
So to the question. How do I put a deferred in a chain that i can reject at any time during the chains execution ? :)
Example fiddle http://jsfiddle.net/ff3jojbo/
Update for clarification
I am using animate.css for my animations. Not jquery animation. I am more interested in how to stop the chain from starting the next stage at any point from user input.
Answer fiddle http://jsfiddle.net/aefkwa8a/
OP's own solution here can fail after several clicks. In particular, if button is clicked while a section is flying in, then the latest demanded section may fly in, then disappear.
This solution is completely different.
Instead of using jQuery's queue/dequeue, it uses a regular
stage1().then(stage2)
promise chain, and stops progress down that chain by removing the CSS animation classes from the animated element and detaching itsanimationend
handler, thus ensuring the promise associated with completion never resolves.As you will see, much of the functionality is factored as jQuery plugins, which makes for convenient, compact syntax.
I believe this solution to be more reliable. Even with lots of manic clicking, I could not defeat it.
Try it here
Try using
.queue()
,.promise()