“面试时,面试官询问如何通过Promise控制100个请求并发” 该如何回答呢?
众所周知,在现代Web开发中,异步已经成为不可或缺的一部分;
当处理大量请求时,如何保持并发是一个非常关键的步骤,Promise异步可以避免代码阻塞一种非常有效的解决方案;
今天我们来讨论一下如何使用Promise控制100个请求的并发操作;
在开始之前,我们简单回顾一下Promise的几个关键的基础知识;
Promise 三种状态:
- pending (等待状态)
- fulfilled (已完成)
- rejected (已拒绝)
Promise 的几个常用方法:
then
该方法用于指定Promise对象状态变为fulfilled时的回调函数onFulfilled,以及状态变为rejected时的回调函数onRejected。
当Promise对象处于fulfilled状态时,将调用onFulfilled函数,并将Promise的结果值作为参数传递给它。
当Promise对象处于rejected状态时,将调用onRejected函数,并将Promise的拒因(错误信息)作为参数传递给它。
该方法返回一个新的Promise对象,可以通过链式调用then()来进行多个操作。
catch
该方法用于指定Promise对象状态变为rejected时的回调函数onRejected。
它相当于调用then(null, onRejected),用于捕获Promise链中任何一个Promise的拒因。
如果Promise链中任意一个Promise被拒绝,且没有提供对应的错误处理回调函数,则会将错误传递给最近的catch()方法来处理。
finally
该方法用于指定Promise对象状态变为fulfilled或rejected时的回调函数onFinally,无论Promise的状态如何,都会执行该回调函数。
在finally()回调函数中,可以执行一些无论Promise成功还是失败都需要进行的清理操作,比如关闭文件、释放资源等。
finally()回调函数不会修改Promise的状态或结果,它只是在Promise链中传递原始的成功或拒绝值。
race
Promise.race()方法接收一个可迭代对象作为参数,并返回一个新的Promise对象。
当传入的可迭代对象中的任意一个Promise对象状态发生变化,新的Promise对象将立即采用该Promise对象的状态和结果。返回的Promise对象将具有与第一个解决的Promise对象相同的状态和结果。
all
Promise.all()方法接收一个可迭代对象作为参数,并返回一个新的Promise对象。
当传入的可迭代对象中的所有Promise对象都变为fulfilled状态时,新的Promise对象将变为fulfilled状态。
如果传入的可迭代对象中的任意一个Promise对象变为rejected状态,则新的Promise对象将立即变为rejected状态,且其拒因为第一个被拒绝的Promise的拒因。
返回的Promise对象将包含一个数组,数组的顺序与传入的可迭代对象中的Promise对象顺序一致,每个元素是对应Promise对象的结果值。
实现思路
1、将100个请求转换成一个请求数组,每个请求都返回一个promise对象;
2、在每个请求中使用 await 来等待请求结果;
3、控制并发请求数量,用一个计数器来跟踪正在进行请求的数量,在每次发起新的请求之前检查计数器是否已经达到最大并发数;如果没有达到最大并发数,增加计数器,bing发起新请求,否则等待之前的请求完成再发起新请求。
实现步骤:
完整代码如下:
// 并发请求数量
const concurrency = 10;
// 请求函数示例
function fetchData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(data => resolve(data))
.catch(error => reject(error));
});
}
// 并发控制函数
async function requests(urls) {
const results = [];
let count = 0;
// 定义异步处理函数
async function handleRequest(url) {
try {
const result = await fetchData(url);
return result;
} catch (error) {
throw new Error(`Error fetching ${url}: ${error}`);
}
}
// 循环发起请求
while (urls.length) {
// 控制并发请求数量
if (count < concurrency) {
const url = urls.shift();
count++;
results.push(handleRequest(url).finally(() => {
count--;
}));
} else {
await Promise.race(results);
}
}
// 等待所有请求完成
await Promise.all(results);
return results;
}
// 100个请求的URL数组示例,可以根据实际需求修改
const urls = [
'https://example.com/api/1',
'https://example.com/api/2',
'https://example.com/api/4',
'https://example.com/api/5',
'https://example.com/api/6',
// ...
'https://example.com/api/100'
];
// 调用并发控制函数
requests(urls)
.then(results => {
console.log('所有请求完成', results);
})
.catch(error => {
console.error('请求出错', error);
});
控制100个请求的并发是一个挑战,但借助Promise的特性,我们可以轻松地管理并发性,并获取每个请求的结果。
通过将请求分成小组,并使用Promise.all()进行并发处理,我们可以更高效地处理大量请求。
说明:本文首发头条,欢迎转载!转载请标注来源即可,无需授权!创作不易,喜欢我的文章,记得添加【关注】哦!再次感谢你的支持!
❀ 长按【点赞】会有惊喜哦!❀
~End~