【问题标题】:AJAX - How to make Asynchronous request one by one without freeze browser?AJAX - 如何在不冻结浏览器的情况下一一发出异步请求?
【发布时间】:2016-03-31 11:28:19
【问题描述】:

我有一个如下的文本区域:

<textarea name="mailist" id="mailist" placeholder="email@domain.com"></textarea>

我想向邮递员发出请求,并使用 "split" 和 "foreach" 将数据(每行电子邮件)发送到某个 URL。它成功了。

但问题是,当我单击提交按钮时,所有请求同时发送。我怎样才能做到:

  • 其他结束后发送请求

  • 异步发出请求

  • 不冻结浏览器

【问题讨论】:

  • 使用.success处理程序..

标签: javascript jquery ajax asynchronous


【解决方案1】:

您要查找的内容称为promise。 jQuery 中的每个$.ajax 函数都返回一个promise。您可以阅读documentation here 以获取更多详细信息。要点是,返回的 Promise 公开了一个名为 then 的函数,可用于以您希望的方式一个接一个地链接请求。

考虑这种类型的 ajax 请求

var request = $.ajax({
  method: 'get',
  url: 'www.google.com'
});

由于它是异步运行的,所以你需要注册处理程序来让你知道请求何时成功完成,或者失败,像这样

request.then(
    function successHandler(response) {
        /* The first function will be called if the request is successful */
    },
    function failureHandler(response) {
       /* The second function will be called if the request fails */
    }
);

使用此模式,您可以等待请求成功或失败,然后再继续下一个请求。

保持较早的代码部分不变

您需要实现一个排序队列。大多数浏览器的合理限制是大约 2-5 个同时请求。一个例子是

var emailAddresses = [/* a list email addresses */];
var MAX_SIMULTANEOUS_REQUESTS = 4;
var CURRENT_REQUESTS = [];

function runRequests(emailAddresses, max, running) {
  while(running.length < max) {
    running.push(createRequest(emailAddress.pop(), running));
  }
  return emailAddresses.length;
}

function createRequest(emailAddress, running) {
  var request = /* Creates requests in some manner */;
  request
    .then(
      function() {
        /* Remove this request from the list of running requests */
        var indexOfRequest = running.indexOf(request);
        running.splice(indexOfRequest, 1);
      },
      function() {
        /* For extra points, add this to a retry queue */
      }
    );
  
  return request;
}

/* Usage */
var interval = setInterval(function() {
  var remaining = runRequests(emailAddresses, MAX_SIMULTANEOUS_REQUESTS, CURRENT_REQUESTS);
  if (remaining === 0) {
    clearInterval(interval);
  }
}, 500);

【讨论】:

  • 我觉得 OP 不会根据他提出的问题来理解这一点。他的问题不是多个请求的瓶颈。
  • @A1rPun 是的,我只想在点击提交按钮时一个一个地发出异步请求
  • @A1rPun 你提出了一个有效的观点。我应该解释一下then 部分
  • @JibiAbraham 应该是running.push(createRequest(emailAddresses.pop(), running));
猜你喜欢
  • 2012-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-02
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多