Javascript 等待带有动画的函数完成,直到运行另一个函数

Javascript 等待带有动画的函数完成,直到运行另一个函数,javascript,jquery,callback,Javascript,Jquery,Callback,我对普通(非ajax)函数有一个问题,每个函数都包含大量的动画。目前我只是在函数之间设置了一个setTimeout,但这并不完美,因为没有浏览器/计算机是相同的 附加说明:它们都有单独的碰撞动画/etc。 我不能简单地把一个放在另一个的回调函数中 // multiple dom animations / etc FunctionOne(); // What I -was- doing to wait till running the next function filled // with a

我对普通(非ajax)函数有一个问题,每个函数都包含大量的动画。目前我只是在函数之间设置了一个
setTimeout
,但这并不完美,因为没有浏览器/计算机是相同的

附加说明:它们都有单独的碰撞动画/etc。

我不能简单地把一个放在另一个的回调函数中

// multiple dom animations / etc
FunctionOne();

// What I -was- doing to wait till running the next function filled
// with animations, etc

setTimeout(function () { 
    FunctionTwo(); // other dom animations (some triggering on previous ones)
}, 1000); 
js/jQuery中是否还有以下内容:

// Pseudo-code
-do FunctionOne()
-when finished :: run -> FunctionTwo()
我知道
$.when()
&
$.done()
,但这些都是针对AJAX的


  • 我的更新解决方案
jQuery有一个名为$.timers的公开变量(由于某些原因,jQuery文档中没有列出该变量),它保存当前正在进行的动画数组

function animationsTest (callback) {
    // Test if ANY/ALL page animations are currently active

    var testAnimationInterval = setInterval(function () {
        if (! $.timers.length) { // any page animations finished
            clearInterval(testAnimationInterval);
            callback();
        }
    }, 25);
};
function animationsTest (callback) {
    // Test if ANY/ALL page animations are currently active

    var testAnimationInterval = setInterval(function () {
        if (! $.timers.length) { // any page animations finished
            clearInterval(testAnimationInterval);
            callback();
        }
    }, 25);
};
基本用途:

// run some function with animations etc    
functionWithAnimations();

animationsTest(function () { // <-- this will run once all the above animations are finished

    // your callback (things to do after all animations are done)
    runNextAnimations();

});
//使用动画等运行一些函数
函数WithAnimations();

AnimationTest(函数(){/这就是你的意思吗

您将有一个函数触发下一个函数,依此类推,即添加另一个函数调用,然后在其底部添加您的
functionONe

如果我遗漏了什么,请告诉我,希望它符合原因
:)

这:

代码:

function hulk()
{
  // do some stuff...
}
function simpsons()
{
  // do some stuff...
  hulk();
}
function thor()
{
  // do some stuff...
  simpsons();
}
functionOne(); // one with animations

animationsTest(functionTwo);
您可以使用jQuery的

您还可以将多个延期打包在一起:

var FunctionOne = function () {
  var
    a = $.Deferred(),
    b = $.Deferred();

  // some fake asyc task
  setTimeout(function () {
    console.log('a done');
    a.resolve();
  }, Math.random() * 4000);

  // some other fake asyc task
  setTimeout(function () {
    console.log('b done');
    b.resolve();
  }, Math.random() * 4000);

  return $.Deferred(function (def) {
    $.when(a, b).done(function () {
      def.resolve();
    });
  });
};

除了Yoshi的答案,我还找到了另一个非常简单的(回调类型)动画解决方案

jQuery有一个名为$.timers的公开变量(由于某些原因,jQuery文档中没有列出该变量),它保存当前正在发生的动画数组

function animationsTest (callback) {
    // Test if ANY/ALL page animations are currently active

    var testAnimationInterval = setInterval(function () {
        if (! $.timers.length) { // any page animations finished
            clearInterval(testAnimationInterval);
            callback();
        }
    }, 25);
};
function animationsTest (callback) {
    // Test if ANY/ALL page animations are currently active

    var testAnimationInterval = setInterval(function () {
        if (! $.timers.length) { // any page animations finished
            clearInterval(testAnimationInterval);
            callback();
        }
    }, 25);
};
基本用途:

function hulk()
{
  // do some stuff...
}
function simpsons()
{
  // do some stuff...
  hulk();
}
function thor()
{
  // do some stuff...
  simpsons();
}
functionOne(); // one with animations

animationsTest(functionTwo);

希望这对一些人有所帮助!

在第一个函数的末尾添加以下内容

return $.Deferred().resolve();
这样调用这两个函数

functionOne().done(functionTwo);

您可以通过回调函数来实现

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable, function() {
          function2(someOtherVariable);
        });
    }
    else {
        doThis(someVariable);
    }
});
函数function1(参数,回调){ …做事 回调();
}

这是一个n调用(递归函数)的解决方案。

这个答案使用的是
ECMAScript 6
标准的JavaScript功能。如果您的目标平台不支持
承诺
,请使用。 您可以在动画调用中使用
.promise()
获得jQuery为动画创建的
延迟对象。将这些
延迟对象
包装成比使用计时器更干净的代码

您也可以直接使用
延迟
,但通常不鼓励这样做,因为它们不遵守承诺/A+规范

生成的代码如下所示:

var p1 = Promise.resolve($('#Content').animate({ opacity: 0.5 }, { duration: 500, queue: false }).promise());
var p2 = Promise.resolve($('#Content').animate({ marginLeft: "-100px" }, { duration: 2000, queue: false }).promise());
Promise.all([p1, p2]).then(function () {
    return $('#Content').animate({ width: 0 }, { duration: 500, queue: false }).promise();
});
请注意,
Promise.all()
中的函数返回承诺。这就是神奇发生的地方。如果在
中,然后
调用中返回承诺,则下一个
调用将等待该承诺得到解决,然后再执行

jQuery为每个元素使用一个动画队列。因此,同一元素上的动画是同步执行的。在这种情况下,您根本不需要使用承诺

我已经禁用了jQuery动画队列,以演示它如何与承诺一起工作

Promise.all()


Promise.race()
也接受一系列承诺,但在第一个
Promise
完成后立即完成。

ECMAScript 6更新

这使用了JavaScript的一个称为Promises的新特性


functionOne()。然后(functionTwo);

您可以使用javascript
Promise
async/await
实现函数的同步调用

假设您希望以同步方式执行存储在数组中的
n
多个函数,下面是我的解决方案

异步函数executeActionQueue(funArray){
var length=funArray.length;
对于(变量i=0;i{
//在此处执行所需的函数
乐趣
。然后((数据)=>{
//是否需要使用数据
决心(正确);
})
.catch((错误)=>{
//处理错误
决心(正确);
});
})
};

executeActionQueue(funArray);
如果
FunctionOne
没有超时或任何东西,您可以调用
FunctionOne();FunctionTwo()
,不是吗?问题是它们都有单独的动画/etc,在不同的文件中-etc。因此它们最终会发生冲突…
$。当
$发生冲突时。完成
不一定只适用于ajax。如果您在FunctionOne中有各种异步任务,希望在启动Function2之前完成这些任务,您可以创建
Def出错的对象,将它们放入数组中,在操作完成时对每个对象调用
resolve()
,然后执行
$。when.apply($,array)。然后(function(){…});
globals是邪恶的,但在这种情况下,可能值得添加一个
isRunning
标志。你保存了我的应用程序,我永远感激回调是正确的JS答案,依我看。我所拥有的只是一个函数调用。我无法修改函数,但我需要在第一次完成后执行我的其他函数。我相信这对一个imation因为他们往往会在一开始就延迟工作,正如他所说,他使用动画,所以您可能需要提到jQuery的
.promise()
外汇交易的方法queue@Bergi你是说jQuery从
animate
返回一个延迟对象吗?否则我就看不出这里需要promise对象了。是的,我不是指
延迟。promise
,但是jQuery方法哦,哇,现在刚刚读了所有这些Yoshi,好东西!我要给它们一个go-tomorr哦,还有试着和promis混在一起