一. 使用场景
使用环境: vue3
当需要处理多个异步任务时,想要控制并行异步任务的数量,不想所有任务同时执行导致产生性能上的问题,
比如当需要同时发起多个网络请求,但又不想一次性发出过多请求导致服务器压力过大或者浏览器资源耗尽时,这个钩子就可以派上用场
二. 效果
测试代码:
const taskControl = useParallelTaskControl(3)const testTaskControl = () => {for (let i = 0; i < 100; i++) {taskControl.addTask(async () => {await new Promise((resolve) => {setTimeout(() => {console.log('执行任务:', i,'剩余任务:', taskControl.remainingTasks.value,'正在执行数量:',taskControl.activeTasks.value )resolve('')}, i % 2 ? 2000 : 3000)})})}
}onMounted(() => {testTaskControl()
})
三. 代码
import {ref, computed, watch} from 'vue';/*** 并行任务控制的自定义钩子* @param maxParallel 最大并行任务数量*/
export function useParallelTaskControl(maxParallel=8) {// 存储待执行的任务数组const tasks = ref<Function[]>([]);// 当前正在执行的任务数量const activeTasks = ref(0);// 当前要执行的任务的索引const taskIndex = ref(0);// 执行单个任务的const runTask = async () => {if (taskIndex.value < tasks.value.length) {activeTasks.value++;taskIndex.value++;const currentTask = tasks.value[taskIndex.value-1];try {await currentTask();} catch (error) {console.error('Task error:', error);} finally {activeTasks.value--;// 任务完成后,检查是否还有任务需要执行await runTask();}}};// 监听任务数组和正在执行任务数量的变化watch(() => [activeTasks,tasks],async () =>{if (activeTasks.value < maxParallel && taskIndex.value < tasks.value.length) {await runTask();}},{deep: true})// 添加任务的函数const addTask = (task: Function) => {tasks.value.push(task);};// 清空任务的函数const clearTasks = () => {tasks.value = [];taskIndex.value = 0;activeTasks.value = 0;};return {// 添加任务addTask,// 清空任务clearTasks,// 正在执行的任务数量activeTasks,// 剩余任务数量remainingTasks: computed(() => tasks.value.length - taskIndex.value)};
}
四. 参数及返回说明
- 参数
最大并行数量: maxParallel [number]
- 返回
添加任务:addTask
需要传一个函数,这个函数会添加到任务队列中
清空任务: clearTasks
正在进行的任务数量:activeTasks
剩余任务数量: remainingTasks