Sample code for using js to implement Ajax concurrent requests to limit the number of requests

Sample code for using js to implement Ajax concurrent requests to limit the number of requests

Description of the problem: When the number of asynchronous requests is uncertain, in order to prevent the accumulation of countless call stacks and memory overflow problems when hundreds of http requests occur in an instant.

Requirements: Limit the number of concurrent requests to less than 3 at a time, and get the response results as quickly as possible.

Same interview question:

Implement a batch request function multiRequest(urls, maxNum) with the following requirements:

  • Requires the maximum number of concurrent connections maxNum
  • Every time a request is returned, a slot is left open for adding a new request.
  • After all requests are completed, the results are printed out in the order of urls.

1. Implementing serial and parallel Ajax based on Promise.all

Usually, asynchronous requests are encapsulated based on promises.

Serial: After one asynchronous request is completed, the next request will be made

Parallelism: multiple asynchronous requests are processed simultaneously

Example: Serial

var p = function () {
 return new Promise(function (resolve, reject) {
  setTimeout(() => {
   console.log('1000')
   resolve()
  }, 1000)
 })
}
var p1 = function () {
 return new Promise(function (resolve, reject) {
  setTimeout(() => {
   console.log('2000')
   resolve()
  }, 2000)
 })
}
var p2 = function () {
 return new Promise(function (resolve, reject) {
  setTimeout(() => {
   console.log('3000')
   resolve()
  }, 3000)
 })
}


p().then(() => {
 return p1()
}).then(() => {
 return p2()
}).then(() => {
 console.log('end')
})

parallel:

var promises = function () {
 return [1000, 2000, 3000].map(current => {
  return new Promise(function (resolve, reject) {
   setTimeout(() => {
    console.log(current)
   }, current)
  })
 })
}

Promise.all(promises()).then(() => {
 console.log('end')
})

Promise.all(promises: []).then(fun: function);

promise.all ensures that all promise objects in the array reach the resolved state before executing the then callback

Promise.all concurrency limit

Meaning: It means that the number of promises executed concurrently at each moment is fixed, and the final execution result remains consistent with the original promise.all.

Ideas and Implementation

This is implemented using recursive calls and setting a maximum number of requests. And each of these requests should continue to be sent recursively when completed, and the specific URL in urls is determined by the passed index to ensure that the final output order is not messed up, but output in sequence

Code implementation:

function multiRequest(urls = [], maxNum) {
 //Total number of requests const len ​​= urls.length;
 // Create an array to save the request results based on the number of requests const result = new Array(len).fill(false);
 // Current completed number let count = 0;

 return new Promise((resolve, reject) => {
  // Request maxNum while (count < maxNum) {
   next();
  }
  function next() {
   let current = count++;
   // Handle boundary conditions if (current >= len) {
    // Once all requests are completed, set the promise to a successful state, and then return result as the promise value!result.includes(false) && resolve(result);
    return;
   }
   const url = urls[current];
   console.log(`start ${current}`, new Date().toLocaleString());
   fetch(url)
    .then((res) => {
     // Save request result result[current] = res;
     console.log(`Completed${current}`, new Date().toLocaleString());
     // If the request is not completed, recurse if (current < len) {
      next();
     }
    })
    .catch((err) => {
     console.log(`end ${current}`, new Date().toLocaleString());
     result[current] = err;
     // If the request is not completed, recurse if (current < len) {
      next();
     }
    });
  }
 });
}

Code implementation:

  // Task list->New task uploadFile() {
   let _this = this;
   var uploadThreadLimitNums = 3,
    uploadThreadNums = 0,
    sendFinishNum = 0,
    resultFinishNum = 0;
   var marks = 0;
   var tasks = [];
   var upload = function () {
    while (uploadThreadNums < uploadThreadLimitNums) {
     if (sendFinishNum >= _this.fileList.length) {
      if (resultFinishNum >= _this.fileList.length) {
       creatTask(); // Complete the request}
      return;
     }
     (function (j) {
      let item = _this.fileList[j];
      let p = new FormData();
      p.append("file", item);
      tasks.push(
       axios({
        method: "post",
        url: `${window.UL_CONFIG.BASEURL}/api/files/upload`,
        data: p,
        onUploadProgress: (progressEvent) => {
         for (let i in _this.rowData) {
          _this.rowData[i].name === item.name
           ? (_this.rowData[i].percent = Math.round(
             (progressEvent.loaded / progressEvent.total) * 100
            ))
           : "";
         }
        },
       })
        .then((res) => {
        /* let obj = {};
         obj.url = `${window.UL_CONFIG.BASEURL}/api/files/${res.data}`;
         obj.fileName = item.name;
         obj.fmt = _this.ruleForm.format;
         obj.samplingRate = _this.ruleForm.samplingRate;
         fileUrls.push(obj); */
        })
        .catch((e) => {
           ? (_this.rowData[i].percent = 0)
         _this.$notify.error({
          title: "Error",
          message: "Service connection error" + item.name + "Unsuccessful upload",
         });
        .finally(() => {
         uploadThreadNums--;
         resultFinishNum++;
         upload();
      );
     })(sendFinishNum);
     uploadThreadNums++;
     sendFinishNum++;
    }
   };
   var createTask = function () {
    axios.all(tasks).then((res) => {
     //Create a new upload task/* let fd1, fd2, calcFlag, flagArr, language;
     fd1 = {};
     flagArr = Object.assign([], _this.ruleForm.checkList);
     if (_this.ruleForm.recognize == "Automatic recognition") {
      flagArr.push("2");
     calcFlag = flagArr.reduce(
      (accu, curr) => Number(accu) + Number(curr)
     );
     _this.ruleForm.recognize == "Automatically recognize"
      ? (language = "")
      : (language = _this.ruleForm.recognize);
     fd1.processContent = calcFlag;
     fd1.remark = _this.ruleForm.remark;
     fd1.name = _this.ruleForm.taskName;
     fd1.fmt = _this.ruleForm.format;
     fd1.samplingRate = _this.ruleForm.samplingRate;
     fd1.language = language;
     fd1.type = 1; // type: 1 audio, 2 video fd1.files = fileUrls; */
     newTask(fd1).then((res) => {
      /* _this.cmpltBtnState = false;
      _this.$store.commit("setTaskId", res.data.id);
      _this.submitFailNumber = res.data.submitFailNumber; */
      _this.$parent.dataInit();
     });
    });
   upload();
  },

This concludes this article about using js to implement sample code for limiting the number of concurrent Ajax requests. For more information about js Ajax concurrent request limitation, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • js implements axios limit request queue
  • How to use Promise in JavaScript to control the number of concurrent requests
  • gin Get JSON body of post request
  • JS implements request dispatcher
  • PHP implements the conversion of chrome form request data into json data used by the interface
  • Detailed explanation of several solutions for JavaScript interruption requests

<<:  Specific use of GNU Parallel

>>:  MYSQL development performance research: optimization method for batch inserting data

Recommend

Solution to MySQL service 1067 error: modify the mysql executable file path

Today I encountered the MySQL service 1067 error ...

Detailed explanation of Json format

Table of contents A JSON is built on two structur...

Sample code using the element calendar component in Vue

First look at the effect diagram: The complete co...

How to deploy a simple c/c++ program using docker

1. First, create a hello-world.cpp file The progr...

MySQL 8.0 Window Function Introduction and Summary

Preface Before MySQL 8.0, it was quite painful to...

How to communicate between WIN10 system and Docker internal container IP

1. After installing the Windows version of Docker...

Detailed explanation of making shooting games with CocosCreator

Table of contents Scene Setting Game Resources Tu...

How to modify the location of data files in CentOS6.7 mysql5.6.33

Problem: The partition where MySQL stores data fi...

Summary of some reasons why crontab scheduled tasks are not executed

Preface I recently encountered some problems at w...

Detailed explanation of MySQL semi-synchronization

Table of contents Preface MySQL master-slave repl...

Two ways to write stored procedures in Mysql with and without return values

Process 1: with return value: drop procedure if e...

Solution to prevent caching in pages

Solution: Add the following code in <head>: ...

MySQL compression usage scenarios and solutions

Introduction Describes the use cases and solution...

jQuery clicks on the love effect

This article shares the specific code of jQuery&#...

JavaScript implements AI tic-tac-toe game through the maximum and minimum algorithm

Without further ado, let’s run the screenshot dir...