1

假设我有多个功能func1,,,func2等等func3......

它们都包含一个 AJAX/async 函数:

function funcX(){ // some ajax request }

如果在一个主函数中我调用func1, func2,func3顺序如下:

$(document).ready(function(){ 

      func1();
      func2();
      func3();
      ...
}

每个 ajax/async 函数的调用是否一定会按照其父函数的顺序执行?起初我以为他们可能是,但我的程序的行为似乎暗示了其他......

如果没有,是否有一个好的(希望很简单?)替代一长串回调?

4

4 回答 4

3

每个 ajax/async 函数的调用是否一定会按照其父函数的顺序执行?

它们应该按顺序执行,但它们的内部回调可以按任何顺序调用。

如果没有,是否有一个好的(希望很简单?)替代一长串回调?

您可以使用promise,并在 promise 解决后执行下一个函数。

这个例子使用 jQuery...

var fn1 = function () {
    var d = $.Deferred();
    setTimeout(function () {
        $("body").text("Callback 1 done.") && d.resolve();
    }, Math.random() * 1300 + 800);
    return d.promise();
};

var fn2 = function () {
    var d = $.Deferred();
    setTimeout(function () {
        $("body").text("Callback 2 done.") && d.resolve();
    }, 500);
    return d.promise();
};

$.when(fn1(), fn2()).then(function () {
    setTimeout(function () {
        $("body").text("All done.");
    }, 300);
});

js小提琴

我们使用$.when()并将我们想要执行的调用函数传递给它。然后我们then()用来显示最终消息(我在setTimeout()此处放置了一个,以便您可以在文档中看到最后解析函数的消息)。

这些函数中的每一个都有自己的延迟对象,它们返回承诺。例如setTimeout(),为了模拟 XHR。执行此回调时,我们会解析延迟对象。

一旦两者都被推迟,我们就会到达回调then()

于 2013-07-03T01:19:35.987 回答
1

为了序列化任务,我编写了一个辅助函数,也可以在我之前的回答中找到:

function serializeTasks(arr, fn, done)
{
    var current = 0;

    fn(function iterate() {
        if (++current < arr.length) {
            fn(iterate, arr[current]);
        } else {
            done();
        }
    }, arr[current]);
}

它需要一个值数组(在您的情况下,这些实际上是函数)、一个循环函数和一个完成处理程序。下面是循环函数:

function loopFn(nextTask, fn) 
{
    fn(nextTask);
}

它接受一个中间完成函数作为第一个参数和上述数组的每个元素。

让一切动起来:

serializeTasks([func1, func2, func3], loopFn, function() {
    console.log('all done');
});

您的函数使用单个参数调用,该参数应传递给 AJAX 成功回调,例如

func1(nextTask)
{
    $.ajax({
        ...,
        success: nextTask
    });
}
于 2013-07-03T01:56:22.000 回答
0

或者看看异步库,它太棒了!

异步

于 2014-02-14T09:20:18.360 回答
0

返回异步结果的顺序不是确定性的,每次都可能很谨慎。

func2 可能在 func1 等之前完成

确保正确的执行顺序很重要。一种模式是在前一个函数的成功回调中调用下一个函数

前任:

$.get("/someUrl",function(){
   $.get("/nextAjaxCall", function(){

   .....
   });
});

如果依赖链很简单,我觉得没必要引入框架来处理

于 2013-07-03T01:21:14.767 回答