从 for 循环内的 AJAX 链中的最后一个 AJAX 请求返回值

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

本文关键字:AJAX 最后一个 请求 返回值 for 循环      更新时间:2023-09-26

我有一个for循环,在一次迭代中,我需要发出四个AJAX请求,然后等到最后一个请求的结果。

  • jQuery Deferred - 获取链式 ajax 调用的结果
  • 在具有固定链调用结束的循环中链接 jquery .when().then()
  • 如何使循环等到异步调用成功后再继续

现在我只知道如何将数据从以前的 promise 传递到另一个承诺,就像在这个很酷的答案中一样,但我需要将上次 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');
                           });
                       }
                        
                    }
                });

不循环的函数在console.log('3333')内部承诺之前开始其console.log...但它们需要等待,直到循环内的 AJAX 调用完成并且循环完成。

现在,如果 AJAX 被拒绝(每秒服务器请求限制),我需要在超时后重复 AJAX - 如何在代码中为承诺内的本机XMLHttpRequest()和返回的 jQuery AJAX 调用设置它?

调或承诺能够处理这种异步控制流...

假设您的原始非工作代码是...

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 函数在进行异步调用时递增堆栈,并在异步回调中递减,在堆栈稳定回零且队列中不再有异步作业时调用repeater。然后,repeater回调重复整个过程,调用getSet并将自身作为回调传递,直到满足条件。

它看起来很简单,对于异步和同步 ajax 请求,您可以使用:

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

在 ajax 成功(完成)回调时更改变量值

上级:

如果您需要对最后一个结果进行回调,我可能会建议您使用这个黑客选项:

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

注意:将1000更改为预期的最大响应时间