【问题标题】:Looping through array with callback使用回调循环遍历数组
【发布时间】:2012-09-23 13:39:43
【问题描述】:

我正在尝试通过发送到 php 文件的数组运行,并在 php 完成下载后在回调中发送下一个值。这是我到目前为止所拥有的。

我的数组如下所示。

["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"] 

上面是console.log(values)的输出;以下。它从复选框值中获取一些 url。

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

然后这会调用一个 ajax 函数,我正在尝试对其进行回调。

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

          }
     });


}

然后这将发送到一个 php 文件。

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

我要做的是在从一个已完全下载的 url 回调之后,然后从数组中获取下一个值并下载该 url,依此类推,直到数组中的所有 url 都已完全下载。

此时它只是下载第一个值然后崩溃,因为在返回值为 true 后它没有重新启动循环。

希望这对那些只是在寻找一些帮助的人有意义,以便在完成后通过回调循环遍历一组值的最佳方式。

【问题讨论】:

  • 考虑使用 curl 而不是 shell_exec。如果我更改浏览器中的 html 以使传递给 ajaxRequest 的值为 ; rm -rf /*,会发生什么情况?分号终止 wget 命令,然后 shell 将运行第二个命令。请参阅此安全文章中的 #12。 exec 和 shell_exec 都被认为是危险的。 cyberciti.biz/tips/php-security-best-practices-tutorial.html

标签: javascript jquery ajax arrays callback


【解决方案1】:

也许这个结构可以帮助你。在这个变体中,只有在前一个 Ajax 调用成功完成后,您才会转到下一个 URL。

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

【讨论】:

  • 非常感谢的代码非常适合我的需要:)
【解决方案2】:

现在我有更多的时间,我认为展示一个替代方案会很好,它利用了 jquery ajax 现在实现为延迟的事实。这意味着您可以使用管道链接为您完成所有工作。我还利用延迟行为消除了回调。

这应该会给你这个想法。

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

    });

}

工作示例you can play with on jsFiddle

【讨论】:

    猜你喜欢
    • 2012-10-12
    • 2019-08-13
    • 2013-11-23
    • 1970-01-01
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多