2015-09-26 58 views
1

基本上我想這樣的:多jQuery的承諾,按順序

function do_ajax_calls(...){ 
    var d = $.Deferred(); 

    $.ajax(args).done(function(){ 

    $.ajax(args).done(function(){ 

     $.ajax(args).done(function(){ 
     d.resolve(); 
     }); 

    }); 

    }) 

    return d.promise(); 
} 

但AJAX調用的次數取決於我傳遞給函數,這是一個數組的論據,所以我不能使用碼。

該函數應該返回一個承諾,只有在最後一次ajax調用完成時才能解析。所以功能需要這樣調用:

do_ajax_calls(....).done(function(){ 
    // here is the callback 
}) 

有誰知道我該怎麼做?

+0

我認爲有某種的EVAL我可以傳遞一個以前建造的字符串,但我不知道如果是這樣的最好的方法 –

回答

2

一個原因承諾是一個大問題,是因爲他們可以鏈接。你可以用你的優勢,以反覆連鎖額外的請求到前一個決議:

function do_ajax_calls() { 
    var dfd = $.Deferred(); 
    var promise = dfd.promise(); 
    var responses = []; 

    function chainRequest(url) { 
     promise = promise.then(function (response) { 
      responses.push(response); 
      return $.ajax(url, { method: 'POST' }); 
     }); 
    } 

    for (var i = 0, length = arguments.length; i < length; i++) { 
     chainRequest(arguments[i]); 
    } 

    dfd.resolve(); 

    return promise.then(function (response) { 
     return responses.slice(1).concat(response); 
    }); 
} 

上面的代碼將返回一個承諾最終解決所有的答覆的數組。如果任何一個請求失敗,承諾將在第一次失敗時被拒絕。

JSFiddle

+0

它看起來並不會奏效。你的循環中的那些ajax調用全部立即被觸發? –

+0

對不起,因爲這個url變量在內部函數中,所以我不認爲這會起作用。我認爲這將是未定義的。我知道,因爲我遇到過這個問題 –

+0

你有一點,儘管這不是變量未定義。我在這裏有一個愚蠢的競爭條件,我無法在小提琴中看到,因爲我每次都發送相同的URL。我已經修復了一遍。 –

1

這裏是它Demo

var counter = 1 ; 

function multipleAjax(loop) 
{ 
    if(counter<loop) 
    { 
     $.ajax(
     { 
      url: 'http://mouadhhsoumi.tk/echo.php', 
      success:function(data) 
      { 
       multipleAjax(loop); 
       $(".yo").append(data+"</br>"); 
       counter++; 
      } 
     }); 

    } 
} 
multipleAjax(5); 
+0

這個答案違背了承諾,即鏈接和可組合性。這與使用純回調沒有區別。 –

1

但AJAX調用的次數取決於我傳遞給函數,這是一個數組

如果它是每個數組元素一個AJAX調用的參數

function do_ajax_calls(args) { 
    return args.reduce(function(promise, item) { 
     return promise.then(function() { 
      return $.ajax(args); // should that be item? 
     }); 
    }, Promise.resolve(true)); 
} 

Promise.resolve(true)是一個「本地」的承諾,即不在IE中可用,但我相信jQuery有一個等效的

這裏有一個JSFiddle演示

0

嘗試使用$.when()Function.prototype.apply()$.map()

function do_ajax_calls(args) { 
    return $.when.apply($, $.map(args, function(request, i) { 
    return $.ajax(request) // `request` : item with `args` array 
    })) 
} 

do_ajax_calls 
.then(function success() { 
    console.log(arguments) 
}, function err() { 
    console.log("err", arguments) 
});