let result = []; for (let i = 0, len = arr.length; i < len; i += chunk) { result.push(arr.slice(i, i + chunk)); } return result; }
// 异步请求方法 function fetchUrl(url) { return new Promise((resolve, reject) => { fetch(url) .then(res => resolve(res)) .catch(err => reject(err)); }); }
// 对url数组进行分块处理 const chunkedUrls = chunk(urls, maxConcurrentNum);
(async function () { try { for (let urls of chunkedUrls) { const promises = urls.map(url => fetchUrl(url)); // 等待所有promises完成执行,并将结果存入results数组中 const results = await Promise.all(promises); console.log('results:', results); } } catch (err) { console.error(err); } })();
以上代码通过将数组分成多个数目相等的小数组,每次最多只开启`maxConcurrentNum`个并发请求,以此来控制并发数量。每当一组请求完成后再发送新的一批请求,可以实现对异步任务的并发控制。
#### Promise.race()
以下是使用Promise.race()方法来控制并发的示例代码:
const promiselist = [];
for (let i = 0; i < 100; i++) {
const promise = fetch(https://example.com/data${i}.json);
promiselist.push(promise);
}
Promise.race(promiselist)
.then(response => {
// handle the fastest response here
})
.catch(error => {
console.error(error);
});
#### async/await
以下是使用async/await方式控制并发请求的示例代码:
async function getData() {
const promiselist = [];
for (let i = 0; i < 100; i++) {
const promise = fetch(https://example.com/data${i}.json);
promiselist.push(promise);
}
const responses = await Promise.all(promiselist);
for (const response of responses) {
// handle each response here
}
}
getData().catch(error => { console.error(error); });
在上面的代码中,我们首先创建了一个async函数,并在该函数中使用for循环来发送所有的请求,并将每个请求的Promise对象存储在一个数组中。 然后,我们使用await关键字来异步等待所有`Promise对象`都被解决,并将解决值存储在一个数组中。 最后,我们在处理每个响应时对数组进行迭代。
如果我们只需要等待最快的请求,我们可以使用`Promise.race()`方法,并将其包装在一个`async函数`中。 这种方法与使用`Promise.all()`的方式相似,只需使用不同的Promise方法即可。
以下是使用`async/await`方式控制并发请求的示例代码,其中使用`Promise.race()`方法:
async function getData() {
const promiselist = [];
for (let i = 0; i < 100; i++) {
const promise = fetch(https://example.com/data${i}.json);
promiselist.push(promise);
}
const response = await Promise.race(promiselist);
// handle the fastest response here
}
getData().catch(error => { console.error(error); });
在上述代码中,我们使用`async函数`来生成`Promise对象`,然后使用`Promise.race()`方法等待最快的解决`Promise对象`,并处理其解决值。
除了`Promise.all()`和`Promise.race()`以及`async/await`等方法外,还有其他用于控制并发请求的可行方法,例如:
1. 手动控制计数器
可以使用变量来手动计数,以控制请求并发数。例如,在循环中,当计数器达到最大并发请求数时,将其用于等待请求完成,然后递增计数器以允许下一个请求。
以下是手动控制计数器的示例代码:
function getData() { const limit = 5; // maximum concurrent requests const dataUrls = ['example.com/data1.json', 'example.com/data2.json', 'example.com/data3.json', 'example.com/data4.json', 'example.com/data5.json', 'example.com/data6.json'];
let counter = 0; const getDataPromise = dataUrl => { return new Promise((resolve, reject) => { fetch(dataUrl) .then(response => { counter--; resolve(response); }) .catch(error => { counter--; reject(error); }); }); };
const getDataPromises = dataUrls.map(dataUrl => { if (counter < limit) { counter++; return getDataPromise(dataUrl); } else { return new Promise(resolve => { const interval = setInterval(() => { if (counter < limit) { counter++; clearInterval(interval);
总结
=============================================================
从转行到现在,差不多两年的时间,虽不能和大佬相比,但也是学了很多东西。我个人在学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。
个人将这段时间所学的知识,分为三个阶段:
第一阶段:HTML&CSS&JavaScript基础
第二阶段:移动端开发技术
第三阶段:前端常用框架
-
推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;如果因为我的笔记太过简陋不理解,可以关注我以后我还会继续分享。
-
大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。