标题:深入理解JS中的Promise.race控制并发量
简介
JavaScript中的Promise是一种处理异步操作的方式,而Promise.race方法则是Promise对象上的一种方法,它与其他方法不同的是,只要其中的一个Promise状态被改变,Promise.race的状态就会被改变。这个方法通常用来控制异步操作的并发数,即同时进行的异步操作数量。
代码示例1:使用Promise.race限制并发请求
// 定义一个限制并发数量的函数limitRun,参数urls为请求地址数组,max为最大并发数
function limitRun(urls, max) {
const results = []; //存放所有请求返回结果的数组
const requestArr = urls.map(url => {
return fetch(url).then(res => res.json()).then(data => {
results.push(data); //将结果存入results数组
console.log(`成功请求${url}所需时间:${Date.now() - start}ms`);
});
});
const start = Date.now(); //开始时间
const requestTasks = []; //存放所有请求任务的数组
let pIndex = 0; //正在执行请求的下标
function addTask() {
if (pIndex >= urls.length) return; //所有请求任务都已开始,则不再添加
const curP = Promise.resolve().then(() => {
return requestArr[pIndex];
});
requestTasks.push(curP); //将当前请求任务存入requestTasks数组
pIndex++; //将正在执行请求的下标移至下一个请求
curP.then(addTask); //将当前请求执行完毕后再递归添加下一个请求
}
while(pIndex < max) { //开始限制并发数
addTask();
}
return Promise.race(requestTasks).then(() => {
return results; //所有请求执行完毕后返回结果数组
});
}
const urls = [url1, url2, url3, url4, url5]; //请求地址数组
const max = 3; //最大并发数
limitRun(urls, max).then(results => {
console.log(`所有请求执行完毕,共耗时${Date.now() - start}ms,请求结果为:`, results);
}).catch(err => {
console.error(`请求出错:`, err);
});
上述代码中,我们定义了一个函数limitRun,用于限制异步操作的并发数。其中,urls为所有请求地址组成的数组,max为最大并发数。
在函数内部,我们首先创建一个results数组,用于存放所有请求返回的结果,在后续将结果存入数组。然后,我们通过map方法遍历urls数组,将每个请求地址转换成一个Promise请求,并将请求的结果存入results数组中。
之后,我们创建一个requestTasks数组,用于存放所有请求任务,并在while循环中,限制并发数。具体实现方式是,我们用pIndex变量保存正在执行请求的下标(初始值为0),用addTask函数递归添加请求任务,使用Promise.resolve().then方法返回一个Promise请求,并将该请求存入requestTasks数组中。而在递归过程中,我们通过curP.then(addTask)在当前请求执行完毕后继续递归添加下一个请求。
最后,通过Promise.race调用requestTasks数组,只要其中有一个请求任务被执行完毕,就会结束所有任务的执行,然后返回results数组,这个数组存放了所有请求的返回结果。
代码示例2:使用Promise.race实现超时限制
function timeoutPromise(ms) { //返回一个延时Promise对象
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(`请求超时,限制${ms}ms`);
}, ms);
});
}
function makeRequest(url, timeout = 3000) { //接收请求地址和超时时间
return Promise.race([
fetch(url).then(res => res.json()),
timeoutPromise(timeout)
]);
}
const url = 'https://jsonplaceholder.typicode.com/posts/1'; //请求地址
makeRequest(url, 2000).then(data => {
console.log(`请求成功,结果为:`, data);
}).catch(err => {
console.error(`请求出错:`, err);
});
在上述代码中,我们定义了一个timeoutPromise函数,接收一个延时时间ms作为参数,返回一个在ms毫秒后reject的Promise。然后,我们又定义了一个makeRequest函数,接收一个请求地址url和超时时间timeout(默认为3000ms)作为参数,返回一个Promise.race方法调用的结果,该方法接收一个数组,包含fetch请求和timeoutPromise。
当然,如果在timeout时间内fetch请求未能返回结果,timeoutPromise就会先返回reject的结果,结束请求的执行。
总结
Promise.race方法在控制并发量和实现超时限制等场景中非常实用。通过掌握Promise.race的使用,我们可以更好地利用Promise对象处理异步操作。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解JS中的Promise.race控制并发量 - Python技术站