jQuery延迟 - 当多个超时任务完成时

时间:2015-03-05 13:28:17

标签: javascript jquery jquery-deferred deferred .when

$.deferred$.when$.done出现了一些问题。

我正在调用一个方法,它在计时器中有几个任务。我正在考虑在此方法中的所有内容都已完成时收到回调,包括计时器中的内容,因此开始查看$.when()$.done()以实现此目的。

我得到的问题是函数在任务完成之前触发,在调用方法时立即触发。所以,我开始玩$.deferredresolve(),但没有设法让任何工作。没有计时器,我可以做到。

这是我称之为方法的地方:

$.when(cover.start()).done(function() {
    console.log("Cover has started.");
});

这是整个方法:

return {

    other: function() {},

    start: function() {
        var dfd = $.Deferred();
        el.filter.animate({
            "opacity": "0.6", "filter": "alpha(opacity=60)"
        }, 2000, "easeInOutCirc", function() {
            el.share.removeClass('fa-spin');

            setTimeout(function() {
                el.share.removeClass('fa-cog').addClass('fa-bars');
            },1000);

            setTimeout(function() {
                el.scroll.animate({
                    "opacity": "1",
                    "bottom": "40px"
                }, 1200, "easeOutBounce", function() {
                    var pulseOptions = { opacity: "0" };
                    setTimeout(function() {
                        el.scroll.pulse(pulseOptions, {
                            duration : 400,
                            pulses: 3,
                            interval: 500,
                            returnDelay: 800
                        });
                    }, 2000);
                    dfd.resolve();
                });
            }, 2000);

            return dfd.promise();

        });
    }

} // end return

正如您所看到的,在我最初的尝试失败后,我将dfd.resolve()添加到我想要回调的位置并尝试返回承诺。但是,该功能仍然过早发射。我哪里错了?

2 个答案:

答案 0 :(得分:4)

问题是,您需要从start方法返回promise

return {

    other: function () {},

    start: function () {
        var dfd = $.Deferred();
        el.filter.animate({
            "opacity": "0.6",
                "filter": "alpha(opacity=60)"
        }, 2000, "easeInOutCirc", function () {
            el.share.removeClass('fa-spin');

            setTimeout(function () {
                el.share.removeClass('fa-cog').addClass('fa-bars');
            }, 1000);

            setTimeout(function () {
                el.scroll.animate({
                    "opacity": "1",
                        "bottom": "40px"
                }, 1200, "easeOutBounce", function () {
                    var pulseOptions = {
                        opacity: "0"
                    };
                    setTimeout(function () {
                        el.scroll.pulse(pulseOptions, {
                            duration: 400,
                            pulses: 3,
                            interval: 500,
                            returnDelay: 800
                        });
                    }, 2000);
                    dfd.resolve();
                });
            }, 2000);


        });
        //need to return from start
        return dfd.promise();
    }

} // end return

答案 1 :(得分:1)

不钓鱼偷APJ的代表'但是出于兴趣,你可以通过利用.delay().promise()来避免回调地狱,这两者都与默认的" fx"动画队列。

以下几行中的某些内容可以解决问题,并且更具可读性:

//animation maps
var maps = [];
maps[0] = { 'opacity':0.6, 'filter':'alpha(opacity=60)' };
maps[1] = { 'opacity':1, 'bottom':'40px' };
maps[2] = { 'opacity':0 };
maps[3] = { 'duration':400, 'pulses':3, 'interval':500, 'returnDelay':800 };

//animation functions
var f = [];
f[0] = function () {
    return el.filter.animate(maps[0], 2000, "easeInOutCirc").promise();
};
f[1] = function () {
    return el.share.removeClass('fa-spin').delay(1000).promise();
};
f[2] = function () {
    return el.share.removeClass('fa-cog').addClass('fa-bars').delay(1000).promise();
};
f[3] = function () {
    el.scroll.animate(maps[1], 1200, "easeOutBounce").promise();
}
f[4] = function () {
    return el.scroll.delay(2000).promise();//delay() could be called on any element. `el.scroll` is arbitrary.
};
f[5] = function () {
    el.scroll.pulse(maps[2], maps[3]);
};

return {
    other: function () {},
    start: function () {
        //animation sequence
        var p = f[0]().then(f[1]).then(f[2]).then(f[3]);
        p.then(f[4]).then(f[5]);
        return p;//<<<< and here's the all important return
    }
}

不确定这是100%正确 - 可能需要一些工作。

值得注意的是,这种方法有性能优势和缺点:

  • 优点:可重复使用的动画地图;可重复使用的功能;
  • 缺点:更自由地使用承诺会导致更大的内存峰值。