preface
Recently saw an interview question, of course, is the title of the passage, Ajax control concurrent requests, feel very interesting, watched under in the community, should be bytes of interview questions, also pretty much bosses about this are summarized, watched, so she also wants to try to summarize, the code below will all posted, if there is any shortage, please point out!
Serialization and parallelism of Ajax
- Serial: The general business requirement is that the next interface needs to use the data returned by the last interface, and the common front-end request library isAxiosIs itself based on
Promise
theHTTP
Library, we directly use the chain call, or useAsync Await
I’m not going to do the demo - Parallelism: multiple requests occurring at the same time, usually used to render the page after all the data has been retrieved, or other operations, mainly based on
Promise.all
The implementation is as follows
The above simulation realized the parallel operation based on promise. all, and the printed results were entered below
Do you feel like this is over? It doesn’t exist? Now for the real thing, imagine a situation where you have to send tens of thousands of requests to a page at the same time, and then do some operations after all of them are successful. The code fails to execute and runs out of memory, which brings us back to the main topic of this article: How to control concurrent Ajax requests? I’ve asked him to output only a certain number of requests at a time until all of them are successful. I’m going to do this in two ways
Ajax’s two main solutions for concurrent request control
Based on thePromise
The recursive implementation
The following two methods use the Tasks array in the image above, so keep that in mind. The first method, which is based on promises, looks like this: When you pass in a concurrency pool, will create the pool a workspace, returned for each workspace (request) to carry out the corresponding tasks, after a successful save, and then continue to take the task (request), until the workspace have no task, of course, failure terminated directly, general train of thought is like this, I made a comment on each line of code below, please take it
Based on theClass
implementation
The second method is based on the Class. The difference is that this method only creates a workspace. The general idea is: Create a workspace to execute tasks (requests), and push all tasks in, but only the corresponding number of concurrent tasks at a time, when less than the number of concurrent tasks, continue to take the task to execute it until there are no more tasks (requests), that’s it
The code shown
The implementation code for both methods is posted here
const delay = function delay(interval) {
return new Promise((res,rej) = > {
setTimeout(() = >{ res(interval) }, interval); })}let tasks = [() = > {
return delay(1000)},() = > {
return delay(1003)},() = > {
return delay(1005)},() = > {
return delay(1002)},() = > {
return delay(1004)},() = > {
return delay(1006)}]// Implement parallelism with promise.all
Promise.all(tasks.map(task= > task())).then(res= > {
console.log(res);
})
// Implement based on Promise
function creatRequest(tasks,pool) {
// The number of requests sent per request pool
pool = pool || 5
// Store the results of each request (in order)
let results = [],
// Together is used to create workspaces. When pool is passed a number, we create workspaces accordingly
// Create an array with the length pool and the value null
together = new Array(pool).fill(null),
// index is the task value obtained each time
index = 0;
together = together.map(() = > {
// Manage based on promises
return new Promise((resolve,reject) = > {
// Create a function and execute it immediately
const run = function run() {
// If the task pool is empty, the request is sent successfully
if(index >= tasks.length) {
resolve()
return
}
// Save index to store the result of the current successful request
let old_index = index,
// Get the current request, and then add index, so index is stored above
Index ++ = index++ = index++ = index++ = index++ = index++ = index++
task = tasks[index++];
// Execute the request
task().then(result= > {
// Save the successful result
results[old_index] = result
// Continue recursively, that is, continue to take the task to the workspace to execute
run();
}).catch(reason= > {
reject(reason)
})
}
// Execute immediately
run()
})
})
// Control the workspace with promise. all, i.e., two requests at a time
return Promise.all(together).then(() = > results)
}
creatRequest(tasks,2).then(results= > {
// If all are successful, all are successful
console.log('success',results);
}).catch(resolve= > {
// If there is only one failure, there is a whole failure
console.log('failure');
})
// Based on Class implementation
function creatRequest(tasks,pool,callback) {
// Parameter constraints and validation
if(typeof pool === 'function') {
callback = pool;
pool = 5
}
if(typeofpool ! = ='number') pool = 5
if(typeofcallback ! = ='function') callback = function () {}
// -------
class TaskQueue {
// The number of runs
runing = 0;
// Queue all tasks that exist
queue = [];
// Store the result of executing the task (request)
results = [];
pushTask(task) {
let self = this
// Push the task into the workspace
self.queue.push(task)
// Execute the logic to send the request
self.next()
}
next() {
let self = this
// Continue to retrieve tasks when the number of tasks in progress is smaller than the number of concurrent tasks
while(self.runing < pool && self.queue.length) {
self.runing++;
// Take a task and delete a task
let task = self.queue.shift();
// Execute the request
task().then(result= > {
// Save the execution result
self.results.push(result)
}).finally(() = > {
// Clear the number of running entries
self.runing--
// Continue with the request
self.next()
})
}
// The loop ends when there are no more tasks
if(self.runing === 0) callback(self.results)
}
}
/ / instantiate
let TQ = new TaskQueue()
tasks.forEach(task= > TQ.pushTask(task))
}
creatRequest(tasks,2.results= > {
console.log(results);
})
Copy the code
conclusion
The above is the summary of this set of interview questions, but also make a record of their own, the follow-up will continue to update the front end of the article, and finally I hope that you front-end partners can stick to learning, technology continues to improve, come on, SAO years!!
Husband learning must be static also, only to learn also, not learn beyond wide only, not beyond into learning. Slow sex can not stimulate the essence, risk impetuous can not cure sex. Year and time chi, meaning and day go, then withered