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
text/typescript
// 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();
};