Is there a way to control the flow of promises in a linear call order?

I still don't have a hard fix on promises. Say I have a code:

selected.eq(i) // blink .fadeOut( 200 ).delay( 50 ).fadeIn( 400 ) .delay( 100 ) .fadeOut( 200 ).delay( 50 ).fadeIn( 400 ); 

and then I call:

 selected.unbind('click') .promise().done(function () { selected.fadeOut(500); }); 

It works as freed - as soon as it blinks, the last fadeOut fires. But when I do the flashing through the plugin (with the option to use jQuery animation), so my whole first part is just one call:

 selected.eq(i).modernBlink({ duration: 750, iterationCount: 3, auto: true} ); 

blinking body:

 ModernBlink.prototype._fallbackAnimation = function _fallbackAnimation( iterationCount ) { var self = this, duration = this.options.duration / 2; if ( iterationCount > 0 || iterationCount === 'infinite' ) { iterationCount = iterationCount === "infinite" ? "infinite" : iterationCount - 1; this.el.animate( { 'opacity': 0 }, duration ).promise().done( function() { self.el.animate( { 'opacity': 1 }, duration ); self._fallbackAnimation( iterationCount ); }); } }; 

so this is a promise based recursive call. The result is different - after the first iteration from blink my code runs because my promise won.

The visual effect is to blink, fade (my part), continue to blink.

My question is - how do you say jQuery blink promises is more important than mine?

NOTE. I can’t directly bind the second part to the first part, because they are scattered throughout the code, and sometimes the first part fails.

Code flashing from Modern Blink by leonderijke. MB was used here as an example!

UPDATE: Large image, I don't know if this is useful or not, but anyway:

 if (Environment.Mode=='blink') // my private settings variable call_blink(); // part 1, presented above call_fade_out(); // part 2, presented above 

That’s why I can’t connect them. I have a similar "configuration" of the code used a little more, so I would like to understand and use it here and in other places.

+5
source share
2 answers

You will need to make modernBlink return a promise that represents the result that you after - the end of the blink. It is simply impossible to intercept an animation that will only be tied in the future. The plugin you use should return a promise, or at least provide a callback; if it is not, you will need to use another or develop it.

In your case, the blink method will need to bind itself to the promise many times, using then :

 ModernBlink.prototype._fallbackAnimation = function(iterationCount) { var self = this, duration = this.options.duration / 2; if (iterationCount === 'infinite' || iterationCount-- > 0) { return this.el.animate({'opacity': 0}, duration).promise() .then(function() { return self.el.animate({'opacity': 1}, duration).promise(); }) .then(function() { return self._fallbackAnimation(iterationCount); }); } else { return this; } }; 

Now your overall picture may look like this:

 if (Environment.Mode=='blink') var step1 = new ModernBlink()._fallbackAnimation(5); else var step1 = jQuery.when(undefined); var step2 = step1.then(call_fade_out); 
+1
source

Try using the animationend event

 $.each(["webkit", "moz", "MS", "o", ""], function (k, v) { selected[0].addEventListener(v !== "" ? v + "AnimationEnd" : "animationend" , function (e) { $(this).unbind('click') .promise().done(function (el) { el.fadeOut(500); console.log("done") }); }) }) 

jsfiddle http://jsfiddle.net/guest271314/x7gqb1g4/


Alternative approach; "infinite" loop, supporting count !== 0 , "stop", calling .stop() , clearQueue() setting the .data() flag

  // v2 // `d` : duration , `count` : iteration (function ($) { $.fn.blink = blink; function blink(d, count) { var el = $(this); $.fx.interval = 0; return el.each(function (i, elem) { var elem = $(elem); elem.data("count", count); return elem.fadeTo(d, "0", "linear", function () { elem.fadeTo(d, "1", "linear", function () { elem.data("count", --count); return (elem.data("count") !== 0 && !elem.data("stop") ? elem.blink(d, elem.data("count")) : elem.stop(true, true).data("stop", false)) }) }) }).promise("fx") }; }(jQuery)); 

 // eg, var selected = $("div") , button = $("button:first") , stop = $("button:last"); selected.on("click", function (e) { // start `$.fn.blink` , log returned `promise` on stop $(this).blink(750, 10).then(function (el) { console.log(el, el.queue(), el.data()); }) }); button.on("click", function () { // unbind `click` event selected.unbind('click') .promise().then(function (el) { el.fadeOut(500); }); }); stop.on("click", function () { // stop animation selected.data("count", null).data("stop", true).clearQueue() }) 

jsfiddle http://jsfiddle.net/guest271314/33ptL9do/

+2
source

Source: https://habr.com/ru/post/1205044/


All Articles