Looping through array with callback

2019-08-30 03:16发布

I am trying to run through a array send to a php file and on a callback send the next value after the php has completed its download. Here what i have so far.

my array come through as follows.

["http://example.com/test1.zip", "http://example.com/test2.zip", "http://example.com/test3.zip", "http://example.com/test4.zip", "http://example.com/test5.zip"] 

above is the output from console.log(values); below. it grabs some urls from checkbox values.

$('.geturls').live('click',function(){

    var values = new Array();
    $.each($("input[name='downloadQue[]']:checked"), function() {
      values.push($(this).val());

       ajaxRequest($(this).val(),function(response){

            console.log(response);

       });  

    });

    console.log(values);

    return false;
});

this then calls a ajax function which i am trying to do a callback on.

function ajaxRequest(urlSend,callback){

    var send = {
            url: urlSend
        }

    $.ajax({
          type: "POST",
          url: "<?php echo base_url(); ?>index.php/upload",
          data: send,
          //dataType: "json",
          //timeout: 8000,
          beforeSend: function() {

          },
          success: function(response) {

             callback('added');

          },
          error: function (response) {

                     callback('false');

          }
     });


}

this will then send to a php file.

function upload(){
   $output = shell_exec("wget {$_POST['url']} 2>&1");      
   return true;
}

What i am trying to do is after the callback from one url which it has download fully then grab the next value from the array and download that url and so on until all the urls in the array are downloaded fully.

at the moment it just downloads the first value and then crashes because it doesn't restart the loop after a return value of true is returned.

Hope this makes sense to someone just looking for some help on the best way to loop through an array of values with a callback after complete.

2条回答
疯言疯语
2楼-- · 2019-08-30 03:39

Now that I have a bit more time, I thought it would be good to show an alternative which takes advantage of the fact that jquery ajax is now implemented as a deferred. Meaning you can use pipe chaining to do all the work for you. I've also eliminated the callbacks by taking advantage of the deferred behavior.

This should give you the idea.

// Use jquery deferred pipe chaining to force 
// async functions to run sequentially


var dfd = $.Deferred(),
    dfdNext = dfd,
    x,
    values = [],

    // The important thing to understand here is that 
    // you are returning the value of $.ajax to the caller.
    // The caller will then get the promise from the deferred.
    ajaxRequest = function (urlSend) {

        var send = {
            url: urlSend
        }

        return  $.ajax({
            type: "POST",
            url: "<?php echo base_url(); ?>index.php/upload",
            data: send,
        });
    };


// Starts things running.  You should be able to put this anywhere 
// in the script, including at the end and the code will work the same.

dfd.resolve();


// Deferred pipe chaining.  This is the main part of the logic.
// What you want to note here is that a new ajax call will 
// not start until the previous
// ajax call is completely finished.
// Also note that we've moved the code that would
// normally be in the callback.
// Finally notice how we are chaining the pipes by
// replacing dfdNext with the return value from the
// current pipe.
for (x = 1; x <= 4; x++) {

    values.push(x);

    dfdNext = dfdNext.pipe(function () {
        var value = values.shift();
        return requestAjax(value).
            done(function(response) {
                // Code here that you would have 
                // put in your callback.
                console.log(response);
            }).
            fail(function(response) {
                console.log(response);
            };

    });

}

Working example you can play with on jsFiddle.

查看更多
Anthone
3楼-- · 2019-08-30 03:44

May be this structure can help you. In this variant you go next URL only after successful completion of the previous Ajax call.

    var arr = ['url0','url1','url2','url3'];
    var index = 0;

    function Run(){
         DoAjax(arr[index]);
    }
    function Next( ){
        if(arr.count = index-1)
        {
             index =0;
             return;  
        }else{
           DoAjax(arr[index ]);
        }
    }    

    function DoAjax(url){

         $.ajax({
          type: "POST",
          url: url,
          data: send,
          beforeSend: function() {

          },
          success: function(response) {
             index ++;
             Next();
             // Addition logic if needed
          },
          error: function (response) {

          }
     });
    }

Run()
查看更多
登录 后发表回答