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

I have a for loop, and in one iteration (of something) I need to make four AJAX requests, then wait until result from the last request.

  • jQuery Deferred - getting result of chained ajax calls
  • chaining jquery .when().then() in a loop with fixed end of chain call
  • How to make for loop wait until Async call was successful before to continue
  • Now I've got only how to pass data from previous promise to another, like in this cool answer, but I need to return the value from the last AJAX call to the outer array (and wait until the last AJAX call is done) and then continue other functions out of the loop.

                    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');
                               });
                           }
                            
                        }
                    });

    Callbacks or promises are capable of handling that kind of async control flow...

    Assuming your original non working code is...

    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);
    }
    

    Callbacks...

    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();
        }
    }
    

    This pattern works something like this...

    getSet is called the first time, with a repeater function that is expected to be called once all async requests are done. The getSet function increments a stack when making async calls, and decrements in the async callbacks, calling the repeater when the stack settles back to zero and there are no more async jobs in the queue. The repeater callback then repeats the whole process, calling getSet and passing itself as the callback until a condition is met.


    It looks simple, for both async and sync ajax requests you may use:

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

    Change your variable value on ajax success(finish) callback

    UPD:

    If you need a callback on the last result I may suggest you this hackly option:

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

    Note: change 1000 to expected maximum response time

    链接地址: http://www.djcxy.com/p/51962.html

    上一篇: 在for循环中调用一个xhr内的ajax

    下一篇: 返回for循环中AJAX链中最后一次AJAX请求的值