Skip to content Skip to sidebar Skip to footer

Is There A Way To Control Flow Of Promises In Linear Call Order?

I still don't have tight grip on promises. Say I have a code: selected.eq(i) // blink .fadeOut( 200 ).delay( 50 ).fadeIn( 400 ) .delay( 100 ) .fadeOut( 200 ).delay( 5

Solution 1:

Try utilizing 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/


An alternative approach ; "infinite" loop by maintaining count !== 0 , "stop" by calling .stop() , clearQueue() setting .data() flag

// v2// `d` : duration , `count` : iteration
    (function ($) {
    $.fn.blink = blink;
    functionblink(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));

// e.g.,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/

Solution 2:

You will need to make modernBlink return a promise that represents the result you are after - the end of the blinking. It simply is impossible to intercept animations that will only be chained in the future. The plugin you're using should return a promise, or at least provide a callback; if it doesn't to that you'll need to use a different one or fork it.

In your case, the blink method will need to repeatedly chain itself to the promise by using then:

ModernBlink.prototype._fallbackAnimation = function(iterationCount) {
    var self = this,
    duration = this.options.duration / 2;

    if (iterationCount === 'infinite' || iterationCount-- > 0) {
        returnthis.el.animate({'opacity': 0}, duration).promise()
        .then(function() {
            return self.el.animate({'opacity': 1}, duration).promise();
        })
        .then(function() {
            return self._fallbackAnimation(iterationCount);
        });
    } else {
        returnthis;
    }
};

Now, your big picture might look like this:

if (Environment.Mode=='blink')
    var step1 = new ModernBlink()._fallbackAnimation(5);
elsevar step1 = jQuery.when(undefined);

var step2 = step1.then(call_fade_out);

Post a Comment for "Is There A Way To Control Flow Of Promises In Linear Call Order?"