为什么我的同步jQuery AJAX回调不起作用?

时间:2017-11-29 14:48:35

标签: jquery ajax synchronous

我想要使用回调来学习jQuery AJAX。所以我创建了这个例子。

<?php 
  sleep($_POST['sleep']);
  echo 'sleep for '.$_POST['sleep'] .'sec';
?>
$(function () {
  var timer = [5,2,3,1,4];

  function sleep(timer) {
    $.ajax({
      url: 'ajax.php',
      data: { sleep: timer },
      type: 'post',
      success: function(d){
        console.log(d);
      },
      error: function(d){
        console.log(d);
      }
    });
  } 

  $('#ajax').click(function(){
    $.each(timer, function(i, e) {
      sleep(e);
    })
  });
});

结果:1,2,3,4,5 我想要的是:5,2,3,1,4(同步)

我知道我可以使用async: false;,但这会挂断我的浏览器,这也被弃用了。所以我想学习使用回调

进行同步

这是我的失败脚本:

<script src="http://code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script>
<script lang="javascript" type="text/javascript">
$(function () {
  var timer = [5,2,3,1,4];

  $.each(timer, function(i, e) {
    sleep(e, function(d) {
      console.log(d);
    });
  });

  function sleep(sleepTimer, callback) {
    $.ajax({
      url: 'ajax.php',
      data: { sleep: sleepTimer },
      type: 'post',
      success: callback,
      error: function(data){
        console.log(data);
      }
    });
  } 
});
</script>

结果:1,2,3,4,5代替5,2,3,1,4

我做错了什么?

更新 感谢有人提醒我这有多糟糕。但我现在没有任何选择。我的朋友需要我的帮助来编辑他的drupal页面。他只有admin previledge(不是sysadmin)。 我只能编辑视图但无法编辑控制器。为什么呢?

  1. 只允许那些允许这样做的总部IT员工。
  2. 需要官僚主义和行政管理(用户要求,会议,质量保证[安全测试+压力测试])。而有趣的是,他们检查所有应用程序,而不仅仅是受我的脚本更改影响的页面
  3. 需要时间。 1个月是非安全更改的最快速度
  4. 嘿..这听起来很有趣吗?即使你只是增加1个空间,我们需要他们(总部工作人员)说的2号要求。这个真实的故事。我知道这是因为我和他在同一个事工中。

    脚本只是通过点击(百元)下载单个文件,我的朋友要我添加复选框以允许他的团队批量下载。我可以添加复选框,并按顺序下载它们(这是我尝试使用同步ajax)。但由于这会挂断他们的浏览器,所以我需要正确的方法来做到这一点。

    我有两个选择:使用phantomjs(中)或同步ajax(简单)

    • 第一个原因:因为他不会付钱给我,因此我选择了简单的道路。
    • 第二个原因:我总是尽量避免使用sync ajax,但现在我想知道如何使用回调来同步ajax。

1 个答案:

答案 0 :(得分:1)

TL; DR:因为它是异步而非同步

您看到的行为对于正常的异步调用完全正确,结果的顺序无法保证,并且可以按任何顺序排列。假设调用之间没有依赖关系,这是触发几个AJAX请求的最佳方法。

出于某种原因,你想同步这样做。

您需要更改代码,以便一次只发送一个请求,等待第一个请求在发送第二个请求之前完成,等等。

您可以通过递归调用sleep,删除(和使用)timers中的第一个值来实现此目的。

$(function () {
    var timer = [5,2,3,1,4];

    function sleep(timers){

        // check that timers is not empty first.
        if (timers == null || timers.length == 0)
            // if it is, we're done
            return;


        // remove the first value from timers
        var timer = timers.shift();

        $.ajax({
            url: 'ajax.php',
            data: {
                sleep: time
            },
            type: 'post',
            complete: function (jqXHR, textStatus) {
                // complete will get called on either success or error
                console.log(jqXHR);
                //recursively call sleep, first time through timers will be [2,3,1,4]
                sleep(timers);
            }
        });
    }

    $('#ajax').click(function(){
        // send the array of values to sleep instead
        sleep(timer);
    });
});