递归回调的机制

时间:2014-10-12 22:41:22

标签: javascript recursion callback

看到这个小提琴:http://jsfiddle.net/ym1aLk25/9/

var s = $('#shake');
var randomTran = function (flag) {
    flag = flag || 0;
    if (flag < 6) {
        var rh = Math.floor((Math.random() * 10) - 5),
            rv = Math.floor((Math.random() * 10) - 5);
        s.transit({x: rh,y: rv}, 50, randomTran.bind(this, ++flag))
    };
};
randomTran();
s.transit({x: 0,y: 0});

我试图让元素摇晃几秒钟,然后回到原来的位置。但它并没有像我预期的那样工作,问题在于回调函数。根据这个问题:If a jQuery function calls itself in its completion callback, is that a recursive danger to the stack?,似乎虽然回调仍在循环,但回调函数之后的代码也正在执行。 那么如何实现我的目标,除了设置超时?我在哪里可以找到关于这种机制的更详细的解释?

2 个答案:

答案 0 :(得分:1)

您的小提琴按预期工作,动画排队(如果.transit()被多次重复调用,它们甚至会排队,因为插件使用jQuery的内部动画队列)。唯一的事情是,最多5个像素的动画50毫秒太快了。我已经增加了时间并打印了计数器in this revision of your fiddle

  

似乎虽然回调仍在循环中,但回调函数之后的代码也正在执行。

没有&#34;循环回调&#34;。回调是传递到函数return 之前回调 - 以及调用{{1}的代码} continue(在您的情况下,是if,.transit()调用结束和}初始化的结束randomTran()大括号。

此代码执行完毕后,可以异步执行其他代码。现在存储的回调是 - 在将来,s.transit({x: 0,y: 0});调用后50ms - 被调用;确实开始另一个转换,安排另一个回调,然后结束。

答案 1 :(得分:0)

randomTran函数中没有回调函数,因此它以异步方式运行。这意味着randomtran()在s.transit({x:0,y:0})之后开始,之后就开始了;被执行。

你可以运行s.transit({x:0,y:0});在randomTran的回调中,让它在其余部分之后执行,如下所示:

var s = $('#shake');
var randomTran = function (flag,callback) {
    flag = flag || 0;
    if (flag < 6) {
        var rh = Math.floor((Math.random() * 10) - 5),
            rv = Math.floor((Math.random() * 10) - 5);
        s.transit({x: rh,y: rv}, 50, randomTran.bind(this, ++flag))
    }else{
      callback();
    }
};
randomTran(0,function(){ //0 is added because randomTran expects flag as first param
  s.transit({x: 0,y: 0}); //this will be executed after randomtran calls back, eg when flag=6
});
但是......我担心你的事情过于复杂,我不确定你想要达到的目标。