递归回调机制



看看这个小提琴: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});

我试着让元素摇晃几秒钟,然后回到原来的位置。但它并没有像我预期的那样工作,问题出在回调函数上。根据这个问题:如果jQuery函数在其完成回调中调用自己,这对堆栈来说是递归的危险吗?,看起来,当回调仍在循环时,回调函数之后的代码也在执行。那么,除了设置超时之外,如何实现我的目标呢?我在哪里可以找到关于这种机制的更详细的解释?

你的fiddle按预期工作,动画被排队(如果.transit()被多次重复调用,它们甚至会被排队,因为插件使用jQuery的内部动画队列)。唯一的问题是,对于一个高达5像素的动画来说,50毫秒太快了。我增加了时间,并在你小提琴的这次修订中打印了计数器。

看起来,当回调仍在循环时,回调函数之后的代码也在执行。

没有"循环回调"。回调被传递给函数,该函数在之前被return调用,并且调用.transit()的代码继续(在您的情况下,它是if的闭合}大括号、randomTran()调用的结束和s.transit({x: 0,y: 0});初始化

一旦该代码完成执行,就可以异步执行其他代码。存储在某个地方的回调现在——将来,在transit()调用后50ms——正在被调用;启动另一个转换,安排另一个回调,然后结束。

您的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
});

但是。。。恐怕你把事情搞得太复杂了,我真的不确定你想实现什么。

最新更新