如何使用具有多个延迟的 when() 来使效果非并发运行

How can I use when() with multiple deferred to make effects run nonconcurrently?

本文关键字:运行 并发 when 何使用 延迟      更新时间:2023-09-26

我正在编写一些简单的UI代码,以便在按下按钮时重新排列布局。

我有一个带有三个表单字段的搜索栏,一个"搜索"按钮,一些文本和一个徽标。按下"搜索"后,按钮、徽标和文本淡出,带有文本字段的栏使用 jquery.animate() 滑到页面顶部,徽标和搜索按钮被赋予不同的 CSS 以重新定位它们,然后在新位置淡入。

我正在尝试使用此JQuery文档使用deferred.done()

我从以下内容开始:

var fades = function () {
    $("#centerSearchText").fadeOut();
    $("#headerImage").fadeOut();
    $("#searchButton").fadeOut();
}
$.when( fades() ).done(function () {
    var positionUpdate = function() { 
        $("#headerImage").css({ "left": "12px", "margin-left": "12px", "margin-top": "12px", "float": "left" });
        $("#searchButton").appendTo("#search_input_table tr:first")
        $("#header").animate({
            top: "0px",
            marginTop: "0px",
        }, 500);
    }
    $.when(cssUpdate()).done(function () {
        $("#headerImage").fadeIn();
        $("#searchButton").fadeIn();
    });
});

。这不起作用,因为每个函数都同时运行。我意识到我没有正确按照示例返回延迟对象,如链接示例中所示,如下所示:

var effect = function() {
    return $( "div" ).fadeIn( 800 ).delay( 1200 ).fadeOut();
};

但是,我需要在完成三个fadeOuts()时返回,而不仅仅是一个。所以我将我的代码更新为以下内容:

var fades = function () {
    return $.when($("#centerSearchText").fadeOut(), $("#headerImage").fadeOut(), $("#searchbtn").fadeOut()).done()
}
$.when( fades() ).done(function () {
    var cssUpdate = function() { 
        return $.when($("#headerImage").css({ "left": "12px", "margin-left": "12px", "margin-top": "12px", "float": "left" }),
                    $("#searchbtn").appendTo("#search_input_table tr:first"),
                    $("#header").animate({
                        top: "0px",
                        marginTop: "0px",
                    }, 500)).done(); 
    }
    $.when(cssUpdate()).done(function () {
        $("#headerImage").fadeIn();
        $("#searchbtn").fadeIn();
    });
});

。其中 UI 元素不再同时运行其效果,因为在初始淡出后未访问任何代码。

谁能启发我我在这里做错了什么?我确定我在某处误解了when()done()的使用,但我无法找到使用多个延迟对象的出色文档来与我的代码进行比较。

您可以使用延迟:

var deferred1 = $.Deferred();
var deferred2 = $.Deferred();
var deferred3 = $.Deferred();
$("#centerSearchText").fadeOut(1000, function() { deferred1.resolve(); } );
$("#headerImage").fadeOut(1000, function() { deferred2.resolve(); } );
$("#searchButton").fadeOut(1000, function() { deferred3.resolve(); } );

$.when(deferred1, deferred2, deferred3).done(function() {
    return when($("#headerImage").css({ "left": "12px", "margin-left": "12px", "margin-top": "12px", "float": "left" }),
                $("#searchbtn").appendTo("#search_input_table tr:first"),
                $("#header").animate({
                    top: "0px",
                    marginTop: "0px",
                }, 500)).done(); 
}
$.when(cssUpdate()).done(function () {
    $("#headerImage").fadeIn();
    $("#searchbtn").fadeIn();
});

http://api.jquery.com/category/deferred-object/

有时在

动画结束时使用函数调用更容易:

$("#header").animate(
{
    top: "0px",
    marginTop: "0px",
}, 500, function()
{
    // call next animation function here, it will be called upon completion
});

鉴于您对所有三个元素都使用未经修改的.fadeOut()动画,更好的方法是将 promise 推送到数组中,并使用 $.when() 评估数组,例如:

// Define vars
var fades = [],
    cssUpdates = [],
    positionUpdate = function() { 
        $("#headerImage").css({ "left": "12px", "margin-left": "12px", "margin-top": "12px", "float": "left" });
        $("#searchButton").appendTo("#search_input_table tr:first")
        $("#header").animate({
            top: "0px",
            marginTop: "0px",
        }, 500);
    },
    cssUpdate = function() { 
        return when($("#headerImage").css({ "left": "12px", "margin-left": "12px", "margin-top": "12px", "float": "left" }),
                    $("#searchbtn").appendTo("#search_input_table tr:first"),
                    $("#header").animate({
                        top: "0px",
                        marginTop: "0px",
                    }, 500)).done(); 
    }
// Fade out
$("#centerSearchText, #headerImage, #searchButton").fadeOut(function() {
    var d = new $.Deferred();
    fades.push(d.resolve());
});
// Listen to fadeOut completion
$.when.apply($, fades).then(function() {
    $.when(cssUpdate()).then(function() {
        $("#headerImage, #searchbtn").fadeIn();
    })
});