簡體   English   中英

來自AJAX鏈中最后一個AJAX請求的返回值,該請求位於for循環內

[英]Return value from last AJAX request in AJAX chain that is inside a for loop

我有一個for循環,在一次迭代中,我需要發出四個AJAX請求,然后等到最后一個請求的結果。

現在,我只知道如何將數據從先前的承諾傳遞給另一個承諾,就像這個很酷的答案一樣 ,但是我需要將最后一個AJAX調用的值返回到外部數組(並等待最后一個AJAX調用完成),然后然后繼續執行其他功能。

  attaches.forEach(function(attach)) { if(attach.val == "val1"){ attachments.push(attach.val1); } if(attach.val == "val2"){ attachments.push(attach.val2); } if(attach.val == val3){ function func1(){ var params = [param1,param2]; return $.post(api, params.join('&')) } function func2(){ console.log('1111'); return new Promise(function(resolve, reject)) { var xhr = new XMLHttpRequest(); xhr.onload = function () { resolve(xhr.response); } xhr.open('GET', img_src); xhr.responseType = 'blob'; xhr.send(); }); } function uploadPhoto(upload_url, bulbSend){ console.log('<Del><F7> function uploadPhoto'); return $.ajax({ url: upload_url, type: 'POST', data: bulbSend, dataType: 'json', processData: false, contentType: false, }); } function saveResult(params){ return $.post(api, params.join('&')) } func1().then(fun1hand()).then(console.log('a32w436bya3b7naua')); function fun1hand(){ return function(dat4a) { return func2().then(func2hand(dat4a)); }; } function func2hand(dat4a){ console.log('2222'); return function(datums){ console.log('3333'); var upload_url = dat4a.upload_url; console.log('UPLOAD__URL BEFORE PROMISE '+upload_url); var bulbSend = new FormData(); bulbSend.append('file1', datums, 'file.jpg'); return uploadPhoto(upload_url,bulbSend).then(func3hand()); } } function func3hand(){ return function(data2){ var params = [data2.param1, data2.param2, data2.param3]; return saveResult(params).then(pushToAttachmentsHandler()); } } function pushToAttachmentsHandler(){ return function(data3){ console.log('PUSUSUSUSSUSUSUUSUS PUSHHHHHHH PUSH DA BAUTTON'); console.log(attachments); return pushDat(data3).then(console.log(attachments)); } } function pushDat(data3){ console.log('1111'); return new Promise(function(resolve, reject) { attachments.push(data3.param3+"_"+data3.param1)); console.log('11111111111'); }); } } }); 

循環外的函數在promises內的console.log('3333')之前啟動console.log ,但是它們需要等待,直到循環內的AJAX調用完成並且循環完成。

現在,如果超時(如果拒絕服務器請求,每秒),我需要在超時后重復AJAX-如何在我的代碼中為promise內的本機XMLHttpRequest()和返回的jQuery AJAX調用設置它?

回調或Promise能夠處理這種異步控制流...

假設您原來的無效代碼是...

for(var i=0; i < 10; i++){
    $.get('http://example.com/rest/users/'+i);
    $.get('http://example.com/rest/posts/'+i);
    $.get('http://example.com/rest/comments/'+i);
    $.get('http://example.com/rest/events/'+i);
}

回調...

var i = 1;

getSet(repeater);

// define a repeater function to be used as recursive callback
function repeater (){
    // increment counter
    i++;
    // if we still have items to process, get another set
    if(i < 10){
        getSet(repeater);
    }
}

function getSet(cb){
    // define queue
    var counter = 0;
    // make four api calls, defining success callbacks, which call the
    // originally passed callback if the counter reaches 0. Increment counter before each request. This means the callback fires only for the last result
    counter++;
    $.get('http://example.com/rest/users/'+i, handleSuccess);
    counter++;
    $.get('http://example.com/rest/posts/'+i, handleSuccess);
    counter++;
    $.get('http://example.com/rest/comments/'+i, handleSuccess);
    counter++;
    $.get('http://example.com/rest/events/'+i, handleSuccess);

    function handleSuccess(data){
        // do something with data
        --counter || cb();
    }
}

這種模式的工作原理如下:

第一次調用getSet ,它具有一個repeater功能,該功能有望在所有異步請求完成getSet調用。 進行異步調用時, getSet函數將堆棧遞增,並在異步回調中遞減,在堆棧恢復為零且隊列中不再有異步作業時,調用repeater 然后, repeater回調重復整個過程,調用getSet並將自身作為回調傳遞,直到滿足條件為止。

它看起來很簡單,對於異步和同步ajax請求,您都可以使用:

var myVar;

yourLoop(function() {
    yourAjax(function(result) {
        myVar = result;
    });
});

在ajax成功(完成)回調中更改變量值

UPD:

如果您需要對最后一個結果進行回調,那么我可能會建議您使用這種不明智的選擇:

var myVar, timeout;

yourLoop(function() {
    yourAjax(function(result) {
        myVar = result;

        clearTimeout(timeout);
        timeout = setTimeout(function() {
            // do something . . .
            console.log('last result', myVar);
        }, 1000);
    });
});

注意:將1000更改為預期的最大響應時間

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM