【问题标题】:asynchronous call with ajaxSubmit - jquery.form使用 ajaxSubmit 进行异步调用 - jquery.form
【发布时间】:2012-10-12 01:43:27
【问题描述】:

我有一个带有特定动作的表格。提交表单后,我发送一个调用此操作的 ajax 调用。另一方面,我正在发送另一个 ajax 调用来更新进度。我做了如下:

    $("form").submit(function() {               
      function callBack()
      {
            if( (this.readyState == 4) && (this.status == 200) )
            {
              console.log(this.responseText);
            }
      }

      function updateProgress (){
        asyncReq('/get_progress?progress='+progress, callBack);
      }

      function asyncReq(url, functionCallBack)
      {
            var request; //request must be a local var to avoid race condition
            try
            {   //for modern browsers
              request = new XMLHttpRequest;
            }
            catch (err)
            {// legacy IE
              request = new ActiveXObject("Microsoft.XMLHTTP");
            }
            request.onreadystatechange = callBack;
            request.open("GET", url, true);
            request.send();
      };
      var progress = $("#progress").val();
      asyncReq('/get_progress?progress='+progress, callBack);
      setTimeout(updateProgress, 2000);
      $(this).ajaxSubmit({async: true});
      return false;
   });

我在这里有 2 个异步 javascript 调用,一个用于提交表单,一个用于更新进度。当我打印出callBack 中的responseText 时,我只能看到0.0 和1.0。那是在调用 ajaxSubmit() 之前和完成之后的一个。我也想在中间获得所有进展的价值。据我了解,asyncReq 的第二次 ajax 调用仅在 ajaxSubmit 完成后调用。谁能告诉我在ajaxSubmit() 完成之前如何进行另一个完整的ajax 调用?

注意:

表单由文件字段和ajaxSubmit组成,解压、处理文件并在处理完每个文件后更新进度表。 get_progress 方法提取该表的进度值。我正在使用 jquery.form.js 通过 ajax 调用提交表单。

【问题讨论】:

  • 当您使用 jQuery,而您手动创建 XMLHttpRequest/ActiveXObject 连接时?让 jQuery 处理这个问题。 api.jquery.com/category/ajax
  • 是的,我尝试使用 $.getScript("/get_progress?progress="+progress),但我不知道为什么,但我一次只能发送一个 ajax 请求。 2 个 ajax 请求没有同时触发!
  • 请检查我刚刚发布的答案是否对您有所帮助
  • 不,这件事是不可能的。因为,我不能向单个服务器发送 2 个请求。我试图启动另一台服务器并将一个请求发送到另一台服务器,但我无法从第二台服务器将响应返回给第一个客户端。在 Rails 服务器中,它说 200 已完成,但在萤火虫控制台中轮询时给了我空的响应。因此,我正在考虑将任务发送给后台工作人员并通过轮询获得响应。那个,我还没有尝试过! :)
  • 为什么不能向单个服务器发送 2 个请求?

标签: jquery ruby-on-rails forms


【解决方案1】:

我不清楚你试图达到什么目的。但是,这是您的代码的简化版本。

function updateProgress(){
    var progress = $("#progress").val();
    $.get('/get_progress?progress='+progress, function(data){
        //***you will get response in data
        //here you write how to handle progress and data
    }
    setTiemout('updateProgress()', 2000)

}
$('form').submit(function(){
    updateProgress();
    $(this).ajaxSubmit({async: true});
})

我不确定ajaxSubmit() 函数实际上对你有什么作用!顾名思义,我猜它只是提交表单。现在,如果您想使用自己的逻辑来显示进度,只需将该逻辑放在*** 标记区域即可。

【讨论】:

  • 是的,这是我的代码的简单版本。 ajaxSubmit() 只是以ajax 请求的形式提交form。然而,我第一次收到来自updateProgress 的回复。但是,通过 ajax 调用提交表单后,在表单提交完成之前,我无法从updateProgress 获得完整的响应。所以,我想在表单提交的ajax调用完成之前调用updateProgress并得到它的响应。
  • 你试过我给出的代码了吗?请尝试后返回。发布错误消息(如果有)
  • 是的,您的代码有效,但我之前提到的问题仍然存在!第一个ajax调用是get_progress,第二个是表单动作,第三个是get_progress。在第二个完成之前,我无法得到第三个的回应。我想在第二个 ajax 调用完成之前得到第三个 ajax 调用的响应。我希望现在很清楚! :)
  • 您在以下语句中的`callBack` 是什么? asyncReq('/get_progress?progress='+progress, callBack);
  • 我刚刚使用了你的代码,它可以工作,除了问题。 callBack 是我问题中的第一个函数。意思是request.readystate改变后要做什么。
【解决方案2】:

两秒后你已经提交了 3 个并发 ajax 请求:

  1. asyncReq('/get_progress?progress='+progress, callBack);
  2. setTimeout(updateProgress, 2000);(稍后运行)
  3. $(this).ajaxSubmit({async: true});

您使用的是旧版浏览器吗?如果是这样,您将遇到两个连接限制。见Max parallel http connections in a browser?How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?

如果对并发请求的数量有限制,您的超时请求将在浏览器上排队并仅在 ajax 表单或第一次进度完成后提交。

【讨论】:

    【解决方案3】:

    您的代码似乎只在 2000 毫秒后更新进度一次。这一行:

    setTimeout(updateProgress, 2000);
    

    您是否尝试过设置更新间隔?这将使该代码每 xxxx 毫秒运行一次。像这样:

    myVar=setInterval(updateProgress,2000);
    

    然后您需要使用clearInterval 来阻止该代码运行。像这样:

    clearInterval(myVar);
    

    请注意,我必须添加变量 myVar。 clearInterval 函数需要它并且需要它才能工作。您可能必须将其全局定义为var myVar

    【讨论】:

    • 更新间隔是什么意思?我不太明白它与 setTimeout 有何不同!
    • setTimeout 只会在您指定的时间后执行一次。 setInterval 将在您每次指定时连续运行。因此,在您的示例中,setTimeout(updateProgress, 2000) 在 2000 毫秒后将运行 updateProgress。就这样,不多说了。其中setInterval(updateProgress, 2000) 在 2000 毫秒后将运行 updateProgress,它将继续每 2000 毫秒运行一次 updateProgress,直到您执行 clearInterval() 函数。
    • @SadikshaGautam 这是我在上一条评论中告诉你的,这个问题在我给定的代码中得到了解决。你可以在我发布的代码模板中注入你的逻辑。
    • 但我的问题不在于定期更新,这很好。问题是,一旦 ajaxsubmit 开始,之后的所有其他更新也不会完成,直到这个 ajaxsubmit 完成。我希望这个 updateProgress 在 ajaxsubmit 运行时定期完成。
    • @SadikshaGautam 这正是我们试图为您提供的以及setInterval 将提供的 - 定期运行 updateProgress。您是否尝试过我们建议的代码? @HungryCoder - 抱歉,我没有看到您对此的评论。它隐藏在“单击此处查看更多 cmets”下。
    【解决方案4】:

    check this

    setTimeout 函数会延迟指定的时间段,然后 触发指定函数的执行。一旦函数 触发 setTimeout 已结束。

    setInterval 函数还会延迟指定的时间 触发特定功能的执行。不同的地方是 触发该功能后,该命令未完成。 相反,它会再次等待指定的时间,然后触发 再次发挥作用,并继续重复触发的这个过程 以指定的时间间隔运行,直到网页 卸载或调用 clearInterval 函数。

    【讨论】:

      【解决方案5】:

      在@HungryCoder 的回复之后,您只缺少一件事。您必须在表单提交中return false

      $('form').submit(function(){
          updateProgress();
          $(this).ajaxSubmit({async: true});
          return false;
      });
      

      如果没有返回 false,表单仍然会做它自然做的事情。或者,您可以捕获提交事件变量。

      $('form').submit(function( e ){
          e.preventDefault();
          updateProgress();
          $(this).ajaxSubmit({async: true});
          return false;
      });
      

      调用e.preventDefault() 也将阻止表单执行它的默认浏览器定义活动(即提交到服务器)。

      【讨论】:

        猜你喜欢
        • 2017-03-17
        • 2020-08-28
        • 1970-01-01
        • 1970-01-01
        • 2016-08-12
        • 1970-01-01
        • 2021-02-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多