如何强制javascript函数同步/顺序执行?

时间:2012-11-24 17:16:06

标签: javascript jquery html asynchronous

我正在创建一个实用程序方法,它有助于使用jQuery顺序淡化元素。正如您在下面的代码中看到的,我正在添加一个额外的类alreadyFadedIn一个标志。在方法调用sequentiallyFadeIn(...)的末尾,我想执行cleanUp,我想删除我在sequentiallyFadeIn(...)方法中所选元素中添加的标志类。

<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function() {

    function sequentialFadeIn(selectorText, speed, display, callBack) {

        display = typeof display !== 'undefined' ? display : "block";

        function helper() {
            nextElementToFadeIn = $(selectorText).not(".alreadyFadedIn").first();
            nextElementToFadeIn.fadeIn(speed, function() {
                $(this).addClass("alreadyFadedIn");
                helper();
            }).css("display", display);
        }
        helper();

        callBack(selectorText);      
    }
    sequentialFadeIn(".toBeFaddedIn", "slow", "inline-block",function cleanUp(selectorText1){
            $(selectorText1).removeClass("alreadyFadedIn");
            console.log("Clean up has been performed.");
                    console.log("Selector Text: " +selectorText1);

        } );

});

</script>

</head>
<body><style media="screen" type="text/css">
.hello {
    background-color: blue;
    height:50px;
    width: 50px;
    display: none;

}
</style>

<div class="hello toBeFaddedIn"></div>
<div class="hello toBeFaddedIn"></div>
<div class="hello toBeFaddedIn"></div>
<div class="hello toBeFaddedIn"></div>
<div class="hello toBeFaddedIn"></div>

</body></html>

在查看inspect元素时,我注意到类alreadyFadedIn没有被删除。在我看来,原因是cleanUp方法与sequentiallyFadeInhelper()方法的主要逻辑异步执行。您还可以注意到日志消息“已执行清理”。甚至在div完成消失之前就已经打印出来了。

如何在cleanUp方法完成主逻辑后执行sequentiallyFadedIn调用?有什么建议吗?

jsfiddle上的代码:http://jsfiddle.net/BztLx/11/

3 个答案:

答案 0 :(得分:4)

您需要检查是否有任何元素仍然被淡入。如果没有元素,请调用清理回调。以下是我实施它的方法:

    if ($(selectorText).is(":not(.alreadyFadedIn)")) {

        //Your main logic
        nextElementToFadeIn = $(selectorText).not(".alreadyFadedIn").first();
        nextElementToFadeIn.fadeIn(speed, function() {
            $(this).addClass("alreadyFadedIn");
            helper();
        }).css("display", display);

    } else {

        //No elements remain, cleanup time
        callBack(selectorText);
    }

在外部条件下,我检查是否至少有一个元素没有淡入,否则我会调用回调。

示范:http://jsfiddle.net/BztLx/12/

答案 1 :(得分:3)

如果您只是重写代码,那么更容易,更清洁,更快......

$(document).ready(function() {

    function sequentialFadeIn(selectorText, speed, display, callBack) {

        display = display || "block";

        var els = $(selectorText),
              i = 0;

        (function helper() {
            els.eq(i++).fadeIn(speed, helper).css("display", display);
            if (callback && i === els.length)
                callback(selectorText); // Not really needed any more
        })();
    }

    sequentialFadeIn(".toBeFaddedIn", "slow", "inline-block", function cleanUp(selectorText1){
        // not really needed any more
       //  $(selectorText1).removeClass("alreadyFadedIn");
    });
});

DEMO: http://jsfiddle.net/BztLx/15/

你正在做方式更多的DOM选择。

答案 2 :(得分:2)

要扩展我的评论,这是一个不使用其他类的简化版本:

function fadeThenNext(element){
    element.fadeIn("fast", function() {
        element=element.next(".toBeFaddedIn");
        if (element.length) fadeThenNext(element);
    });
}
fadeThenNext($(".toBeFaddedIn").first());

演示:http://jsfiddle.net/BztLx/17/

[更新] 如果元素不是兄弟姐妹,则为更通用的版本:

function fadeSequence(elements){
    elements.first().fadeIn("fast", function() {
        fadeSequence(elements.slice(1));
    });
}
fadeSequence($(".toBeFaddedIn"));

小提琴:http://jsfiddle.net/BztLx/22/