在内部动画完成之前不要执行函数

时间:2011-01-20 18:49:44

标签: javascript jquery concurrency

The Terse Version

假设我有一个使用jQuery动画的函数。我不希望在动画完成之前再次调用此函数。

例如,当调用下面的函数时,我不希望在内部计时器例程完成之前再次调用它:

function doSomething() {
   ... blah blah blah ...

   someElement.fadeOut(999, function() {
       // Don't let doSomething get invoked until the fadeOut animation has finished
   });
}

冗长问题

我正在开发一个新闻自动收报机小部件,它在封面下面是一个无序列表。一次只显示列表元素的子集。每隔五秒钟,列表中的第一个项目就会淡出,然后从列表顶部删除并添加到列表的底部。

循环新闻项目的功能如下:

function advanceTicker(id) {
    // Get the first item
    var firstItem = $(id + ' li:first');
    var firstItemMarkup = firstItem.html();

    // Fade out the first item then move it to the bottom
    firstItem.fadeOut(999, function() {
        $(this).remove();  // Remove the first item

        // Tack the first item to the end of the list
        $(id).append('<li style="display:none">' + firstItemMarkup + '</li>');

        // Make the new first item visible
        $(id + ' li:first').show();
    });
}

当新闻项目每五秒循环一次时,上述功能很有效,但是如果我想在用户点击页面上的一个按钮时调用此功能(进入下一个项目),那么事情会变得混乱用户多次单击该按钮。也就是说,新闻自动收报机中有重复的内容。

我理解为什么(或者至少我认为我这样做) - 在第一次按键点击时执行的fadeOut调用在再次点击按钮时尚未完成,因此{{1在第二个按钮上单击并选择再次附加。

我的假设是我需要确保在“正在进行”时不调用此firstItem函数。有一种优雅的方式来做到这一点?我现在拥有的 - 感觉有点像黑客 - 是一个标志变量,如下所示:

advanceTicker

上述方法感觉不对,闻起来像是竞争条件问题。

1 个答案:

答案 0 :(得分:3)

我所知道的所有实现都存在于单个线程上下文中,或者只允许单独的线程存在于沙箱中,因此我认为您的实现没有任何问题。