UNPKG

uniapp-use-request

Version:

一个功能强大且高度可配置的 Vue 3 Composition API 请求 Hook,灵感来源于 [ahooks](https://ahooks.js.org/hooks/request/use-request) 和 [SWR](https://swr.vercel.app/)。它内置了缓存、防抖、节流、轮询、重试、请求队列和并发控制等特性。

174 lines (154 loc) 4.51 kB
// hooks/useRequest/queue.ts // 请求队列项接口 interface QueueItem<T = any> { id: string; priority: number; execute: () => Promise<T>; resolve: (value: T | PromiseLike<T>) => void; reject: (reason?: any) => void; } /** * 请求队列类 * 用于管理请求队列和并发控制 */ class RequestQueue { private queue: QueueItem[] = []; private running: Set<string> = new Set(); private maxConcurrent: number = 6; // 默认最大并发数 private isProcessingScheduled = false; // 标志是否已安排处理 /** * 设置最大并发数 * @param max 最大并发数 */ setMaxConcurrent(max: number): void { this.maxConcurrent = max > 0 ? max : 1; this.processQueue(); } /** * 添加请求到队列 * @param item 队列项 * @returns Promise */ enqueue<T>(item: Omit<QueueItem<T>, 'resolve' | 'reject'>): Promise<T> { return new Promise<T>((resolve, reject) => { const queueItem: QueueItem<T> = { ...item, resolve, reject }; // 添加到队列 this.queue.push(queueItem); // 按优先级排序,高优先级在前 this.queue.sort((a, b) => b.priority - a.priority); // 延迟处理队列,以收集同一事件循环中的所有请求 if (!this.isProcessingScheduled) { this.isProcessingScheduled = true; Promise.resolve().then(() => { this.processQueue(); this.isProcessingScheduled = false; }); } }); } /** * 取消队列中的请求 * @param id 请求ID */ cancel(id: string): void { // 从队列中移除 const index = this.queue.findIndex(item => item.id === id); if (index !== -1) { const item = this.queue[index]; this.queue.splice(index, 1); item.reject(new Error('Request cancelled')); } // 如果正在执行,标记为已取消(实际取消由调用方处理) if (this.running.has(id)) { this.running.delete(id); } } /** * 处理队列 */ private processQueue(): void { // 如果当前运行的请求数小于最大并发数,且队列中有等待的请求 while (this.running.size < this.maxConcurrent && this.queue.length > 0) { const item = this.queue.shift()!; this.running.add(item.id); // 执行请求 item.execute() .then(result => { item.resolve(result); }) .catch(error => { item.reject(error); }) .finally(() => { this.running.delete(item.id); this.processQueue(); // 处理下一个请求 }); } } /** * 获取队列长度 */ get length(): number { return this.queue.length; } /** * 获取当前运行的请求数 */ get runningCount(): number { return this.running.size; } /** * 清空队列 */ clear(): void { // 拒绝所有等待中的请求 this.queue.forEach(item => { item.reject(new Error('Queue cleared')); }); this.queue = []; } } // 导出请求队列单例 export const requestQueue = new RequestQueue(); /** * 添加请求到队列 * @param id 请求ID * @param priority 优先级 * @param execute 执行函数 * @returns Promise */ export const enqueueRequest = <T>( id: string, priority: number, execute: () => Promise<T> ): Promise<T> => { return requestQueue.enqueue({ id, priority, execute }); }; /** * 取消队列中的请求 * @param id 请求ID */ export const cancelQueuedRequest = (id: string): void => { requestQueue.cancel(id); }; /** * 设置最大并发数 * @param max 最大并发数 */ export const setMaxConcurrent = (max: number): void => { requestQueue.setMaxConcurrent(max); }; /** * 清空请求队列 */ export const clearRequestQueue = (): void => { requestQueue.clear(); };