2

我有以下JS方法:

    var foo = function() {
        var dfd = $.Deferred();
        console.log('foo');
        dfd.resolve();
        return dfd.promise();
    };
    var ajaxCall1 = function () {
        var dfd = $.Deferred();
        $.ajax({
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            url: 'xxxxxxx',
            data: { },
            success: function(response) {
                dfd.resolve();

            }
        });
        return dfd.promise();
    };
    var ajaxCall2 = function () {
        var dfd = $.Deferred();
        $.ajax({
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            url: 'xxxxxxx',
            data: {},
            success: function (response) {
                dfd.resolve();

            }
        });
        return dfd.promise();
    };
    var ajaxCall3 = function () {
        var dfd = $.Deferred();
        $.ajax({
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            url: 'xxxxxxx',
            data: {},
            success: function (response) {
                dfd.resolve();

            }
        });
        return dfd.promise();
    };

我通过这段代码给他们打电话:

    foo().done(function () {
        return ajaxCall1();
    }).done(function () {
       return  ajaxCall2();
    }).done(function () {
        return ajaxCall3();
    });

问题是 ajaxCall2 在 ajaxcall1 成功之前被调用。你能帮我解决这个问题吗?当前一个成功发生时,我需要一一进行ajax调用。

4

5 回答 5

2

使用 $.when

var deferredObject = $.ajax({});
$.when(deferredObject)
 .then(function(){
     var deferredobject2 = $.ajax({});
     $.when(deferredobject2)
      .then(function(){ alert('after 2nd ajax call');});

  }); 
于 2012-04-19T05:47:10.647 回答
1

首先,您可以直接返回 $.ajax 调用的结果,因为它们已经是 Promise(不需要中间 Deferred):

var ajaxCall1 = function () {
    return $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        url: 'xxxxxxx',
        data: { }
    });
};
var ajaxCall2 = function () {
    return $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        url: 'xxxxxxx',
        data: {}
    });
};
var ajaxCall3 = function () {
    return $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        url: 'xxxxxxx',
        data: {}
    });
};

其次,您想要使用的是.pipe()来有效地链接调用:

foo().pipe(function () {
    return ajaxCall1();
}).pipe(function () {
    return  ajaxCall2();
}).pipe(function () {
    return ajaxCall3();
}).done(function() {
    // call1, call2 and call3 done in sequence
}).fail(function() {
    // one of the ajax requests failed
});
于 2012-04-20T05:29:40.573 回答
0

简化。

function foo() {
    var dfd = $.Deferred();
    console.log('foo');
    dfd.resolve();
    return dfd.promise();
}

function ajaxCall1() {
    return $.ajax({
        type: 'POST',
        dataType: 'json',
        url: 'xxxxxxx',
        data: { },
        success: function(response) {
            console.log('ajaxCall1 success');
        }
    });
    return dfd.promise();
}

// and so on for ajaxCall2 and ajaxCall3

提高。

foo().done(function () {
    ajaxCall1().done(function () {
        ajaxCall2().done(function () {
            ajaxCall3();
        });
    });
});

http://jsfiddle.net/mattball/LxjDS/


进一步阅读:

于 2012-04-19T03:51:08.790 回答
0

与其他答案相同,除了使用Frame.js简化回调

var responses = [];
for(var i=0; i<1000; i++){
    Frame(function(callback){
        $.ajax('myserver.api', { 
            data:i, 
            type:'post', 
            complete:function(response) { 
                responses.push(response);
                callback();
            }
        });
    });
}
Frame.start();

通常情况下,像这样用 AJAX 请求猛击浏览器会导致浏览器挂起,并且响应变量将按照它们被接收的顺序返回,而不是它们被发送的原始顺序。在这里添加 Frame 可以对所有这些进行排序出去。

或者你可以用它来扁平化回调:

Frame(function(next){
    foo().done(next);
});
Frame(function(next){
    ajaxCall1().done(next);
});
Frame(function(next){
    ajaxCall2().done(next);
});
Frame(function(next){
    ajaxCall3().done(next);
});
Frame(function(next){
    //do more stuff
    next();
});
Frame.start();
于 2012-04-19T05:17:24.963 回答
0

我在大量使用 SharePoint Web 服务时遇到过类似的问题 - 您经常需要从多个源中提取数据才能继续工作。

为了解决这个问题,我将这种功能嵌入到我的 AJAX 抽象库中。您可以轻松定义一个请求,该请求将在完成时触发一组处理程序。但是,每个请求都可以使用多个 http 调用来定义。这是组件:

DepressedPress.com 上的 DPAJAX

这个非常简单的示例使用三个调用创建一个请求,然后按照调用顺序将该信息传递给单个处理程序:

    // The handler function
function AddUp(Nums) { alert(Nums[1] + Nums[2] + Nums[3]) };

    // Create the pool
myPool = DP_AJAX.createPool();

    // Create the request
myRequest = DP_AJAX.createRequest(AddUp);

    // Add the calls to the request
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [5,10]);
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [4,6]);
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [7,13]);

    // Add the request to the pool
myPool.addRequest(myRequest);

Note that unlike many of the other solutions provided this method does not force single threading of the calls being made - each will still run as quickly as the environment allows but the handler will only be called when all are complete. The component also supports user-defined numbers of requests so you can force single-threading easily if you like. It also supports the setting of timeout values and retry attempts if your service is a little flakey.

I've found it insanely useful (and incredibly simple to understand) for this kind of work.

于 2012-09-08T15:03:30.580 回答