problem
There are currently 40 asynchronous requests that need to be sent, but for some reasons, we must control the number of concurrent requests at the same time to less than 6, and at the same time, we must get the response results as quickly as possible. What should I do?
This question is very similar to a classic interview question:
实现一个批量请求函数 multiRequest(urls, maxNum),要求如下:
• 要求最大并发数 maxNum
• 每当有一个请求返回,就留下一个空位,可以增加新的请求
• 所有请求完成后,结果按照 urls 里面的顺序依次打出
achieve
Promise serial and parallel
- Serial: After an asynchronous request is completed, proceed to the next request;
- Parallel: multiple asynchronous requests at the same time;
Serial
Serial is to initiate the next http request again after a successful http request;
Advantages
- http requests are in order;
- The latter http request can get the return value of the previous request;
Disadvantages:
- The maximum number of concurrent requests for the same domain name of the browser is not used, and there will only be one http request at the same time, which greatly extends the response time.
const p = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("1000");
resolve();
}, 1000);
});
};
const p1 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("2000");
resolve();
}, 2000);
});
};
const p2 = function () {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("3000");
resolve();
}, 3000);
});
};
p().then(() => {
return p1();
}).then(() => {
return p2();
}).then(() => {
console.log("end");
});
parallel
resolve
in the parameter array reach the 060be115e39553 state, the then
callback is executed.
Disadvantages:
- If there are tens of thousands of http requests, promise.all will issue tens of thousands of http requests in an instant, which is likely to cause countless call stacks to accumulate and cause memory overflow.
- If any promise is rejected, it will not enter then;
const promises = () => {
return [1000, 2000, 3000].map((current) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(current);
resolve();
}, current);
});
});
};
Promise.all(promises()).then(() => {
console.log("end");
});
Promise.all concurrency limit
Promise.all concurrency limit refers to: the promise
each moment is fixed, and the final execution result remains the same as the original Promise.all
.
Chestnut: Request concurrency limit with the same request interface but different parameters
Add the maximum concurrent number maxRequestNum, and return after all requests are completed.
advantages:
- Utilize the maximum number of concurrent requests for the same domain name in the browser to quickly get all return values, reduce response time, and will not cause stack overflow.
Disadvantages:
- All requests are completed before returning. The screen will be blank for a long time and the user experience will be bad.
const multiRequest = (fetch, params = [], maxRequestNum = 6) => {
const paramsLength = params.length;
let result = new Array(paramsLength).fill(false);
let sendCount = 0;
let finishCount = 0;
return new Promise((resolve) => {
while (sendCount < maxRequestNum && sendCount < paramsLength) {
next();
}
function handleResult(current, res) {
finishCount ++;
result[current] = res;
if (sendCount < paramsLength) {
next();
}
if (finishCount >= paramsLength) {
resolve(result);
}
}
function next() {
let current = sendCount++;
const param = params[current];
fetch(param).then((res) => {
handleResult(current, res)
}).catch((err) => {
handleResult(current, err)
});
}
});
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。