current position:Home>A front-end interview question -- implementing an encapsulated Ajax device (promise version)
A front-end interview question -- implementing an encapsulated Ajax device (promise version)
2022-04-29 09:18:12【from_ the_ star】
Title Description
Implement a package ajax device , Functions include
- Limit the number of messages sent at one time ajax Number of requests m individual
- timeout Limit
- retry n Time
Pre knowledge
XMLHttpRequest
XMLHttpRequest(XHR) Object is used to interact with the server . adopt XMLHttpRequest You can request specific... Without refreshing the page URL, get data . This allows web pages to , Update the local content of the page .XMLHttpRequest stay AJAX It's used a lot in programming
A brief introduction , You can go to MDN Check out .
open(): Initialize a request
send(): Request
abort(): If the request has been sent , Then stop the request immediately .
readyState、status attribute : Used to determine whether the request is completed . commonly readyState !== 4 && status === 0
It means that the request is completed .
timeout attribute : Indicates the maximum request time of the request ( millisecond ), Beyond that time , The request will automatically terminate .
Fetch
Fetch API Provides an interface to obtain resources ( Including cross domain requests ).fetch() Must accept a parameter —— The path of resources . Whether the request is successful or not , It all returns one Promise object ,resolve In response to the request Response. You can also pass an optional second parameter init( See Request).
Just mention what you need , We'd better go to MDN Check out .
fetch() Method is used to initiate a request to obtain resources . It returns a promise, This promise Will be... After the request response resolve, And send back Response object .
It should be noted that : When you receive a wrong HTTP When the status code , from fetch() Back to Promise Will not be marked as reject, Even if the response is HTTP Status code is 404 or 500, It will also Promise The status is marked with resolve ( But it will resolve The return value of Response Object's ok Property is set to false ). Only if the network fails or the request is blocked ,Promise The status will be marked as reject.
suspend fetch
The browser has started for AbortController and AbortSignal Interface ( That is to say Abort API) Add experimental support , Allow like Fetch and XHR Such an operation is aborted before it is completed .
Their thinking
ajax have access to XMLHttpRequest encapsulation , You can also use off the shelf Fetch Transform it to realize additional functions .
XMLHttpRequest
advantage : flexible , High operability , There is an abort request 、 timeout 、 A variety of event monitoring methods
shortcoming : trouble
Fetch
advantage : Easy to use , Send a request with credentials 、 Upload JSON 、 Common scenarios such as uploading file data can be covered
shortcoming : Only... Can be set Request object , No, XMLHttpRequest, Properties without timeout settings API
here xhr It's still used Fetch, I'm so lazy , I don't want to listen to events and judge , Encapsulating a series of get、post Method, etc. . about Fetch Properties without timeout settings API, With the help of timer and abort fetch Of API complete .
Implementation part
queue
I used a queue here , To save the sent ajax request , When the maximum number of requests is reached , Just keep it in the queue , Waiting for the connection .
Implement a queue , Generally, it is necessary to join the team 、 The way out of the team , In line with the principle of first in, first out , At the same time, we should also realize that the query team is full 、 The status of the team empty .
Because if you enter and leave the team too many times, the array will be too large , In order not to cause waste , What is implemented here is a circular queue .
// Implement a queue
class Queue{
constructor(size){
this.size = size;
this.data = Array(size);
this.front = 0;
this.rear = 0;
}
in(url){
if(this.isFull()) return false;
this.data[this.rear] = url;
this.rear = (this.rear+1)%this.size;
return true;
}
out(){
let res = null;
if(this.isEmpty()) return res;
res = this.data[this.front];
this.data[this.front] = null;
this.front = (this.front+1)%this.size;
return res;
}
isFull(){
return this.front===this.rear&&this.data[this.size-1];
}
isEmpty(){
return this.front===this.rear&&!this.data[this.size-1];
}
}
Main part
The code is implemented in get Request as an example , as follows :( The main ajax request 、 Retry and timeout settings are both in reTryRequest Function )
class axios {
/** * initialization axios * @param maxSize Limit simultaneous requests ajax Number of requests m * @param poolSize Size of the request pool */
constructor(maxSize = 3, poolSize = 100) {
this.requests = new Queue(poolSize);
this.maxSize = maxSize;
this.curSize = 0;
}
// only get, It can be set by value transfer fetch The second parameter to meet more needs
get(url,timeout,reTryCount) {
let res,rej;
const currentPro = new Promise((resolve, reject)=>{
res = resolve;
rej = reject;
});
if (!this.requests.isFull()) {
this.requests.in([url,res,rej,timeout,reTryCount]);
this.tryRequestUrl();
} else {
rej(new Error(" The request pool is full "));
}
return currentPro;
}
// Into the request pool , Start judging whether to send a request according to the maximum request
tryRequestUrl() {
if (this.curSize < this.maxSize) {
if(this.requests.isEmpty()){
console.log(` Complete all requests `);
}else{
let [url,resolve,reject,timeout,reTryCount] = this.requests.out();
if (url) {
console.log(` Start connecting ${
url}`);
this.reTryRequest(url,resolve, reject,timeout,reTryCount);
this.curSize++;
}
}
} else {
console.log(` Waiting for the connection `);
}
}
// Request and be responsible for retrying
reTryRequest(url,resolve, reject,timeout,reTryCount) {
let TriedCount=0;
if(!reTryCount) reTryCount = 0;
const xhr = ()=>{
let t;
let controller = new AbortController();
let signal = controller.signal;
if(timeout){
t = setTimeout(()=>{
controller.abort();
},timeout);
}
fetch(url,{
signal})
.then((response)=> {
if(response.ok){
t&&clearTimeout(t);
resolve(response.json());
this.curSize--;
this.tryRequestUrl();
}else{
retryFunc()
}
})
.catch((e)=>{
retryFunc(e)
})
}
// Try to retry after failure
const retryFunc = (e)=>{
if(TriedCount < reTryCount){
TriedCount++;
console.log(" Timeout start retry ");
xhr();
}else{
reject(url+" The maximum number of retries has been reached ");
this.curSize--;
this.tryRequestUrl();
}
}
xhr();
}
}
Test code :
const a = new axios();
a.get("/simple/get",520,1).then((v)=>console.log(v));
a.get("/simple/get1",520,2).then((v)=>console.log(v));
a.get("/simple/get2",520,1).then((v)=>console.log(v));
a.get("/simple/get3",520,1).then((v)=>console.log(v));
Author's dish , If there is any wrong , Please point out , Thank you very much !
copyright notice
author[from_ the_ star],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/119/202204290630081780.html
The sidebar is recommended
- Lesson 3 of ROS quick start - subscriber subscriber of ROS
- A lifeless face
- Mock in Vue JS preliminary simple use
- The Java Web servlet triggers the alert box on the front end
- CSS sets the color of the small vertical bar in front of the title
- Incomplete display of CSS background image
- [front end learning notes] save the front-end related codes
- Precautions for AWS serverless design dynamodb
- AWS serverless design - apigateway
- AWS serverless design lambda
guess what you like
AWS serverless design - firewall WAF
AWS serverless design-s3
Python repeated element determination function program
Nginx direction agent solves cross domain Problems-2
The foundation of JavaScript
DOM based on JavaScript
Javascript based BOM
JavaScript advanced functions
Basic summary of JavaScript advanced
Object oriented JavaScript
Random recommended
- JavaScript advanced threading mechanism and event mechanism
- HTML+CSS
- Introduction to less
- CSS3 media query
- Learn about bootstrap
- JQuery learning
- Ajax case
- Ajax sends a post request
- Ajax sends get requests
- Ajax notes
- Ajax learning notes
- Relearn react (1) - recognize the life cycle
- Small problems encountered by react usereducer and Solutions
- CSS realizes the square of adaptive screen width
- Nginx + ModSecurity setup
- Bootstrap web job
- bootstrap
- Swoft 2. X Foundation (HTTP, database, redis)
- Docker actual combat case 2: nginx load balancing
- Vue basic syntax
- Go basic syntax 3 (socket, httpserver)
- Nginx configures HTTPS and calls http
- Nginx parsing vulnerability
- How can the backend package Vue projects quickly
- Netty configures WSS protocol access through nginx (Practical)
- Total permutation problem_ Not containing the same element and containing the same element_ Leetcode46_ Leetcode47_ Backtracking solution + java code
- How to upload and download files using Axios in nodejs
- Vue excel file upload
- CondaHTTPError: HTTP 000 CONNECTION FAILED for url < https://conda.anaconda.org/fastai/noarch/repodat
- Multi function environmental monitoring pole scheme based on wireless gateway
- JPS in Hadoop, but http://hadoop01:50070/ How to solve the problem if there is no interface? 500ha70 cluster can't be accessed?
- Tool class for obtaining specific information in HTTP request
- UAV project tracking record 65 - wireless transceiver module circuit
- UAV project tracking record 76 - wireless transceiver module circuit
- Basic concept of angular velocity
- Front end login password encryption and decryption
- Vue parent-child component mutual transmission and intermodulation
- Vue nested loop array, select one of them and add the selected style
- The Vue seamless scroll list scrolls automatically
- Vue line graph moves dynamically to the right