AJAX - 如何在没有冻结浏览器的情况下逐个进行异步请求?

Ahm*_*adi 2 javascript ajax jquery asynchronous

我有一个textarea如下:

<textarea name="mailist" id="mailist" placeholder="email@domain.com"></textarea>
Run Code Online (Sandbox Code Playgroud)

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

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

  • 在另一方结束后发送请求

  • 异步提出请求

  • 不冻结浏览器

Jib*_*ham 5

你在寻找什么被称为a promise.$.ajaxjQuery中的每个函数都返回一个promise.您可以在此处阅读文档以获取更多详细信息.要点是,返回的promise公开了一个被调用的函数then,它可以用来按照你想要的方式一个接一个地链接请求.

考虑这种类型的ajax请求

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

由于它是异步运行的,因此您需要注册处理程序,以便在请求成功完成或失败时通知您,如此

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 */
    }
);
Run Code Online (Sandbox Code Playgroud)

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

保留早期代码段完整

您需要实现一个排序队列.大多数浏览器都有大约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);
Run Code Online (Sandbox Code Playgroud)