JavaScript uses promise to handle multiple repeated requests

JavaScript uses promise to handle multiple repeated requests

1. Why write this article?

You must have read a lot of articles about handling duplicate requests. Most of them are divided into two versions: returning duplicate requests before the response is returned and using throttling/anti-shake to indirectly avoid frequent user operations. In the process of using them recently, I found that these two versions still have some limitations in some scenarios.

2. Problem scenario

As shown in the picture, the business card component should be displayed at the top and bottom of my h5 page. The information of these business cards is obtained through an interface. When this component is initialized on the current page, two repeated requests will occur.

At this point you will face several choices:

1. Do not process duplicate requests.

  • Disadvantage 1: Causes unnecessary waste of resources and increases server pressure
  • Disadvantage 2: There is a limit on the number of concurrent HTTP requests in the browser. If there are many requests for the first screen of the page and there is no hierarchical loading, it is easy to cause request blocking, affecting the user's ability to see the main content in the first place.

2. Return duplicate requests directly. This is also the practice of some articles, but this approach has a limitation, which is that it directly determines that subsequent repeated requests are invalid requests.

  • Invalid request scenario: The user clicks a button to query or save. Before the request result is returned, subsequent clicks are basically considered invalid requests and should be blocked. Of course, this problem can be circumvented by adding throttling/anti-shake to the button
  • Why it is not applicable to the current scenario: Both business card components require data to render. If the second repeated request is returned, the business card of one of the components will have no data.

3. Extract the request from the component and put it in the parent business page, and then pass it into the component as props.

  • Benefit: Two components can share a copy of data with just one request.
  • Limitations: Only applicable to a single business page. In fact, this component is used by many business pages. Even if the requested function is extracted into a public API, it must be called once when each business page is initialized, and then passed into the component as props.

3. Solution

Core Idea

  • Initialize an array of handleList
  • Before sending a request, determine whether it is a duplicate request based on whether the input parameters are the same
    • Non-repeated requests: Add the request parameters and the Promise returned by the request to the array
    • Repeat request: Use find to directly return the corresponding Promise
  • After the request is completed, remove the request information previously added in handleList.

This solution can be used for anything, whether using axios, jq, fetch, or applet request. Here is the implementation principle. When using it, just put the corresponding code in the corresponding request time.

Code Sample

let handleList = [] // request list/**
 * Simulate request * @author waldon
 * @date 2020/6/9
 */
const httpRequest = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`Request successful, timestamp: ${new Date().getTime()}`)
    }, 1000)
  })
}
/**
 * Request related processing * @author waldon
 * @date 2020/6/9
 * @param {String} url -
 * @param {Object} requestObj - request parameters * @returns {Promise} - request promise
 */
function requestTest(url, requestObj = {}) {
  // Because the input parameters generally do not involve complex types, JSON.stringify is sufficient for serialization comparison. // One limitation is that the order of input parameters will change, which will affect the judgment. However, this special change generally does not occur in repeated requests. // If there is such a demand, switch to other recursive comparison APIs. Lodash also has similar APIs.
  const sameHandle = handleList.find(
    (item) => item.url === url && JSON.stringify(item.requestObj) === JSON.stringify(requestObj)
  )
  if (sameHandle) {
    // If the same request is encountered, the promise of the previous request is returned directly
    console.log(`There is a duplicate request, return directly`)
    return sameHandle.handle
  }
  const handle = new Promise((resolve, reject) => {
    httpRequest()
      .then((res) => {
        resolve(res)
      })
      .catch((err) => {
        reject(err)
      })
      .finally(() => {
        // Regardless of the request result, the corresponding request needs to be removed handleList = handleList.filter(
              (item) =>
                item.url !== url && JSON.stringify(item.requestObj) !== JSON.stringify(requestObj)
            )
      })
  })
  handleList.push({ url, requestObj, handle })
  return handle
}

// *******************************I am starting to use the gorgeous dividing line *********************************
const params = {
  name: 'waldon'
}
requestTest('/ajax/sameUrl', params).then((res) => {
  console.log(`First request result`, res)
  console.log(`handleList:`, handleList)
})
requestTest('/ajax/sameUrl', params).then((res) => {
  console.log(`repeat request result`, res)
  console.log(`handleList:`, handleList) // There is always only one request in the request list setTimeout(() => {
    console.log(`handleList after request is completed:`, handleList) // After the request is completed, the request corresponding to handleList will be cleared}, 100)
})
setTimeout(() => {
  // Delay the request by 500ms because we set the interface to return after 1s, so we should get the same result requestTest('/ajax/sameUrl', params).then((res) => {
    console.log(`repeat request result`, res)
    console.log(`handleList:`, handleList)
  })
}, 500)

Output

If there is a duplicate request, return directly If there is a duplicate request, return directly The result of the first request is successful, and the timestamp is: 1621650375540
handleList:[
{
url: '/ajax/sameUrl',
requestObj: { name: 'waldon' },
handle: Promise { 'Request successful, timestamp: 1621650375540' }
}
]
Repeat the request and the request is successful. The timestamp is: 1621650375540
handleList:[
{
url: '/ajax/sameUrl',
requestObj: { name: 'waldon' },
handle: Promise { 'Request successful, timestamp: 1621650375540' }
}
]
Repeat the request and the request is successful. The timestamp is: 1621650375540
handleList:[
{
url: '/ajax/sameUrl',
requestObj: { name: 'waldon' },
handle: Promise { 'Request successful, timestamp: 1621650375540' }
}
]
handleList after request is completed: []

Code address codepen

https://codepen.io/waldonUB/pen/ZEeeONM

Points to note

  • Do not add or delete data in the response. Because the object reference address in the Promise returned by repeated requests is the same, any change will cause data pollution. In special cases, you can shallowly copy the response result and then process it, or add corresponding assertions.
  • When processing repeated requests, it is best to prompt in the log and annotate the reasons and usage scenarios in the component to prevent others from making mistakes.
  • Be prepared to handle request failures in extreme cases, set the effective time to clear and remove request information, and avoid memory leaks caused by excessive useless request information accumulated in closures.

This is the end of this article about using promise in JavaScript to handle multiple repeated requests. For more information about js promise multiple repeated requests, 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:
  • Detailed explanation of the initial use of Promise in JavaScript asynchronous programming
  • Example analysis of the usage of node.js Promise object
  • Detailed explanation of using Promise in WeChat applet JS script to optimize function processing
  • js uses Promise to implement simple Ajax caching
  • Using Promise in JS to implement traffic light example code (demo)
  • Detailed explanation of the use of Promise in JavaScript
  • Detailed explanation of Promise usage in javascript

<<:  How to mount a disk in Linux and set it to automatically mount on boot

>>:  How to query the minimum available id value in the Mysql table

Recommend

Vue uses the video tag to implement video playback

This article shares the specific code of Vue usin...

A complete tutorial on installing Ubuntu 20.04 using VMware virtual machine

Ubuntu is a relatively popular Linux desktop syst...

MySQL uses custom functions to recursively query parent ID or child ID

background: In MySQL, if there is a limited level...

HTML uses form tags to implement the registration page example code

Case Description: - Use tables to achieve page ef...

Div picture marquee seamless connection implementation code

Copy code The code is as follows: <html> &l...

A simple example of how to implement fuzzy query in Vue

Preface The so-called fuzzy query is to provide q...

5 commonly used objects in JavaScript

Table of contents 1. JavaScript Objects 1).Array ...

Example of downloading files with vue+django

Table of contents 1. Overview 2. Django Project 3...

Solution to the CSS height collapse problem

1. High degree of collapse In the document flow, ...

Tutorial on how to connect and use MySQL 8.0 in IDEA's Maven project

First, let's take a look at my basic developm...

5 issues you should pay attention to when making a web page

1. Color matching problem <br />A web page s...

Form submission refresh page does not jump source code design

1. Design source code Copy code The code is as fol...

Analysis of Context application scenarios in React

Context definition and purpose Context provides a...

How to use vue3+TypeScript+vue-router

Table of contents Easy to use Create a project vu...