【发布时间】:2011-01-21 03:01:01
【问题描述】:
简洁版
假设我有一个使用 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 调用在再次单击按钮时尚未完成,因此选择了相同的 firstItem在第二个按钮上单击并再次附加。
我的假设是我需要确保在“进行中”时不会调用此 advanceTicker 函数。有没有一种优雅的方式来做到这一点?我现在拥有的 - 感觉有点像黑客 - 是一个标志变量,如下所示:
var inAnimation = false;
function advanceTicker(id) {
if (!inAnimation) {
inAnimation = true;
...
firstItem.fadeOut(999, function() {
...
inAnimation = false;
});
}
}
上面的方法感觉不对,闻起来像一个竞争条件问题。
【问题讨论】:
-
不要在 JavaScript 中阻塞 - 它会冻结 UI。
-
@Brian:我认为“阻止”在这里用错了——我相应地更新了问题标题。
-
啊,在那种情况下,@ChaosPandion 的回答对我来说似乎是合理的。
-
@Scott...你想做这样的事情吗? jsfiddle.net/KeesCBakker/yQagG
标签: javascript jquery concurrency