如何避免回调链?

时间:2011-03-08 09:02:05

标签: javascript jquery callback

我需要严格按顺序调用一堆函数。下一个函数等到上一个函数完成之前也是非常重要的。

现在我正在使用链式回调:

callMe1(function(){
    callMe2(function(){
        callMe3(function(){

            callMeFinal();

        });
    });
});

这有效,但似乎有点难看。

对不同方法的任何建议?

5 个答案:

答案 0 :(得分:32)

如果您使用jQuery,那么您可以使用queue来链接函数。

$(document)
  .queue(callMe1)
  .queue(callMe2);

其中callMeX的格式应为:

function callMeX(next) {
    // do stuff
    next();
}

答案 1 :(得分:6)

您可以实施“堆叠”系统:

var calls = [];

function executeNext(next) {
    if(calls.length == 0) return;
    var fnc = calls.pop();
    fnc();
    if(next) {
        executeNext(true);
    }
}

/*To call method chain synchronously*/
calls.push(callMe3);
calls.push(callMe2);
calls.push(callMe1);
executeNext(true);

/*To call method chain asynchronously*/
calls.push(callMe3);
calls.push(function(){
    callMe2();
    executeNext(false);
});
calls.push(function(){
    callMe1();
    executeNext(false);
});

答案 2 :(得分:3)

不确定这是否会对您有所帮助,但using deferreds in jQuery 1.5上有一篇很棒的文章。它可能会稍微清理你的链......

另外,我对Can somebody explain jQuery queue to me的回答有一些使用队列来确保顺序调用的例子。

答案 3 :(得分:0)

您可能希望将参数传递给函数,我不相信您在撰写本文时可以。然而...

function callMe1(next) {
    console.log(this.x);
    console.log("arguments=");
    console.log(arguments);
    console.log("/funct 1");
    this.x++;
    next();
}
function callMe2(next) {
    console.log(this.x);
    console.log("arguments=");
    console.log(arguments);
    console.log("/funct 2");
    this.x++;
    next();
}
function callMe3(next) {
    console.log(this.x);
    console.log("arguments=");
    console.log(arguments);
    console.log("/funct 3");
    this.x++;
    next();
}
var someObject = ({x:1});
$(someObject).queue(callMe1).queue(callMe2).queue(callMe3);

答案 4 :(得分:0)

使用与.queue一起播放的匿名函数来完整地包装函数,参数完整无效。

在Jquery.Queue()

中传递参数
var logger = function(str, callback){
    console.log(str);
    //anything can go in here, but here's a timer to demonstrate async
    window.setTimeout(callback,1000)
}

$(document)
.queue(function(next){logger("Hi",next);})
.queue(function(next){logger("there,",next);})
.queue(function(next){logger("home",next);})
.queue(function(next){logger("planet!",next);});

关于JSFiddle的示例:http://jsfiddle.net/rS4y4/