
回复
在HarmonyOS的ArkTS中,对网络请求并发控制进行优化,可避免因过多并发造成性能下降。以下是几种常见的优化策略及示例代码:
请求队列管理的核心思路是把所有的网络请求放入队列中,按照一定规则逐个处理,避免同时发起过多请求。
class RequestQueue {
private queue: Array<() => Promise<any>> = [];
private maxConcurrent: number;
private activeCount: number = 0;
constructor(maxConcurrent: number) {
this.maxConcurrent = maxConcurrent;
}
addRequest(request: () => Promise<any>): void {
this.queue.push(request);
this.processQueue();
}
private async processQueue(): Promise<void> {
if (this.activeCount >= this.maxConcurrent || this.queue.length === 0) {
return;
}
const request = this.queue.shift();
if (request) {
this.activeCount++;
try {
await request();
} catch (error) {
console.error('Request error:', error);
} finally {
this.activeCount--;
this.processQueue();
}
}
}
}
// 使用示例
const queue = new RequestQueue(3);
function makeNetworkRequest(id: number): () => Promise<any> {
return async () => {
console.log(`Starting request ${id}`);
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(`Finished request ${id}`);
};
}
for (let i = 1; i <= 10; i++) {
queue.addRequest(makeNetworkRequest(i));
}
令牌桶算法是常用的限流算法之一。它会以固定速率往桶里添加令牌,每个请求需要获取一个或多个令牌才能被处理。
class TokenBucket {
private capacity: number;
private rate: number;
private tokens: number;
private lastRefillTime: number;
constructor(capacity: number, rate: number) {
this.capacity = capacity;
this.rate = rate;
this.tokens = capacity;
this.lastRefillTime = Date.now();
}
private refill(): void {
const now = Date.now();
const elapsedTime = now - this.lastRefillTime;
const newTokens = (elapsedTime / 1000) * this.rate;
this.tokens = Math.min(this.capacity, this.tokens + newTokens);
this.lastRefillTime = now;
}
canExecute(): boolean {
this.refill();
if (this.tokens >= 1) {
this.tokens--;
return true;
}
return false;
}
}
// 使用示例
const bucket = new TokenBucket(10, 2);
function makeRateLimitedRequest(id: number): () => Promise<any> {
return async () => {
while (!bucket.canExecute()) {
await new Promise(resolve => setTimeout(resolve, 100));
}
console.log(`Starting rate-limited request ${id}`);
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(`Finished rate-limited request ${id}`);
};
}
for (let i = 1; i <= 10; i++) {
makeRateLimitedRequest(i)();
}
连接池技术是预先创建一定数量的网络连接并管理起来,当有请求时从连接池中获取可用连接,使用完后归还,避免频繁创建和销毁连接带来的性能开销。
class ConnectionPool {
private pool: Array<{ inUse: boolean; connection: any }> = [];
private maxConnections: number;
constructor(maxConnections: number) {
this.maxConnections = maxConnections;
for (let i = 0; i < maxConnections; i++) {
this.pool.push({ inUse: false, connection: this.createConnection() });
}
}
private createConnection(): any {
// 这里模拟创建网络连接
return {
sendRequest: () => {
console.log('Sending request using connection');
}
};
}
getConnection(): any | null {
for (const item of this.pool) {
if (!item.inUse) {
item.inUse = true;
return item.connection;
}
}
return null;
}
releaseConnection(connection: any): void {
for (const item of this.pool) {
if (item.connection === connection) {
item.inUse = false;
break;
}
}
}
}
// 使用示例
const connectionPool = new ConnectionPool(3);
function makePooledRequest(id: number): () => Promise<any> {
return async () => {
const connection = connectionPool.getConnection();
if (connection) {
try {
console.log(`Starting pooled request ${id}`);
connection.sendRequest();
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(`Finished pooled request ${id}`);
} finally {
connectionPool.releaseConnection(connection);
}
} else {
console.log(`No available connection for request ${id}`);
}
};
}
for (let i = 1; i <= 10; i++) {
makePooledRequest(i)();
}
这些策略可依据实际需求组合使用,进而实现更高效的网络请求并发控制。