我怎么能调用一些javascript函数但是,等待之前的函数已经完成了?

时间:2011-03-04 15:19:00

标签: javascript jquery jquery-plugins callback closures

我想调用一些函数,但等待前一个函数已经完成。 我知道jQuery在几个函数中提供了一个回调参数,但我想学习如何在我自己的jQuery插件中实现这个行为。所以情况就是这样:

在阅读my previous question的答案后,我写了这个:

    (function(callback){
        $('#art1').animate({'width':'1000px'},1000);
        callback();
    })((function(callback2){
        $('#art2').animate({'width':'1000px'},1000);
        callback2();
    })(function(){
        $('#art3').animate({'width':'1000px'},1000);
    }));

但不行。我再次尝试并写下了这个:

    animate1(function(){
        animate2(function(){
            animate3();
        })
    });

    function animate1(callback){
        $('#art1').animate({'width':'1000px'},1000);
        callback();
    }
    function animate2(callback){
        $('#art2').animate({'width':'1000px'},1000);
        callback();
    }
    function animate3(callback){
        $('#art3').animate({'width':'1000px'},1000);
        callback();
    }

但仍然无法正常工作。三个动画仍然同时开始。我希望他们一个接一个地被召唤。但不使用:

    $('#art1').animate({'width':'1000px'},1000,'linear',function(){
        $('#art2').animate({'width':'1000px'},1000,'linear',function(){
            $('#art3').animate({'width':'1000px'},1000);        
        });        
    });  

5 个答案:

答案 0 :(得分:3)

这就是Buffer的用途:

var Buffer = function(handler) {
    var tasks = [];
    // empty resolved deferred object
    var deferred = $.when();

    // handle the next object
    function handleNextTask() {
        // if the current deferred task has resolved and there are more tasks
        if (deferred.isResolved() && tasks.length > 0) {
            // grab a task
            var task = tasks.shift();
            // set the deferred to be deferred returned from the handler
            deferred = handler(task);
            // if its not a deferred object then set it to be an empty deferred object
            if (!(deferred && deferred.promise)) {
                deferred = $.when();
            }
            // if we have tasks left then handle the next one when the current one 
            // is done.
            if (tasks.length > 0) {
                deferred.done(handleNextTask);
            }
        }
    }

    // appends a task.
    this.append = function(task) {
        // add to the array
        tasks.push(task);
        // handle the next task
        handleNextTask();
    };
};

然后我们只为动画创建一个任务处理程序,一个动画任务并将任务附加到缓冲区。

function handleAnimation(task) {
    var def = $.Deferred();
    $(task.id).animate(task.props, task.timeout, task.options function() {
        def.resolve();
    });
    return def.promise();
}

function AnimationTask(id, props, timeout, options) {
    this.id = id;
    this.props = props;
    this.timeout = timeout;
    this.options = options;
}

var buffer = new Buffer(handleAnimation);
buffer.append(new AnimationTask("#art1", {
    "width": "1000px"
}, 1000, "linear");
buffer.append(new AnimationTask("#art2", {
    "width": "1000px"
}, 1000, "linear");
buffer.append(new AnimationTask("#art3", {
    "width": "1000px"
}, 1000, "linear");

这使用延迟的jQuery魔法一个接一个地运行任务。将它们链接起来可能要容易得多。

这也可行:

(function(callback){
    $('#art1').animate({'width':'1000px'},1000, function() {
         callback();
    });
})((function(callback2){
    $('#art2').animate({'width':'1000px'},1000, function() {
         callback2();
    });
})(function(){
    $('#art3').animate({'width':'1000px'},1000);
}));

答案 1 :(得分:0)

我建议你Jquery Defered Object

答案 2 :(得分:0)

以下是在您自己的jquery扩展中使用回调的示例:

http://jquery-howto.blogspot.com/2009/11/create-callback-functions-for-your.html

答案 3 :(得分:0)

您需要将回调作为参数传递给动画调用:

function Animate(afterFirst,afterSecond) {
  $('#art1').animate({'width':'1000px'},1000,function(afterFirst,afterSecond) {
    afterFirst();
    $('#art2').animate({'width':'1000px'},1000,function(afterSecond) {
      afterSecond();
      $('#art3').animate({'width':'1000px'},1000);
    });
  });
}

答案 4 :(得分:0)

如果你只想让你的动画一个接一个地运行,你只需要设置queue:true作为一个动画属性。 http://api.jquery.com/animate/

相关问题