我把 AI 写的并发请求控制器手写了一遍——3 个语义我当时根本讲不清
ææ AI åçå¹¶åè¯·æ±æ§å¶å¨æåäºä¸éââ3 个è¯ä¹æå½æ¶æ ¹æ¬è®²ä¸æ¸
kyriewen 2026-08-20 0 é 读6åéClaude Code çæçå¹¶åè¯·æ±æ§å¶å¨ï¼å¨æé¡¹ç®éè·äºä¸ä¸ªå¤æï¼é¶äºæ ãç´å°ä¸å¨ææ´ç代ç ï¼è¯çèªå·±è§£é"è¿æ®µä¸ºä»ä¹è¿ä¹å"ââ第 3 è¡å°±å¡ä½äºã
äºæ¯æå ³æææå·¥å ·ï¼æå®æåäºä¸éãåå®ç¡®è®¤ï¼æå½æ¶ä¸æçè¯ä¹æ 3 个ï¼èè¿ 3 ä¸ªï¼æ°æ°æ¯"ä¸åºäºå°±æ°¸è¿ä¸æ´é²ãä¸åºäºå°±æ¥ä¸å°æ ¹å "çé£ç§ã
å æ¾ 3 个é®é¢ï¼
- 为ä»ä¹ç¨
Promise.raceçå¾ ï¼è䏿¯æ´ç´è§çåæ¹Promise.allï¼ - 为ä»ä¹æ°ç»éåç䏿¯ä»»å¡ promise æ¬èº«ï¼èæ¯å®æ´¾çåºæ¥ç"æ¸ ç promise"ï¼
- å¦æå ¶ä¸ä¸ä¸ªä»»å¡å¤±è´¥äºï¼è¿ä¸ªæ± åå°åºä¼åçä»ä¹ï¼
ä¸ä¸ªé½è½ç䏿¥çï¼è¿ç¯æç« å¸®ä½ ç 10 åéï¼çä¸ä¸æ¥çï¼å¾ä¸çã
AI åççæ¬
彿¶çæçæ ·åï¼ç®ååå¤§è´æ¯ï¼
function createPool(limit: number) {
const executing: Promise<void>[] = [];
return async function run<T>(task: () => Promise<T>): Promise<T> {
const p = Promise.resolve().then(task);
const e = p.then(() => {
executing.splice(executing.indexOf(e), 1);
});
executing.push(e);
if (executing.length >= limit) {
await Promise.race(executing);
}
return p;
};
}
ä¹ä¸ç没æ¯ç ï¼å¹¶åæä¸éãæ»¡äºèªå¨çãåæµå ¨ç»¿ãä½ä¸é¢ 3 个é®é¢ï¼æå½æ¶ä¸ä¸ªé½çä¸å©ç´¢ï¼åªä¼è¯´"忣å®ä¸ç´æ¯è¿ä¹åç"ã
è¯ä¹ä¸ï¼race æ¯"èµ°å®ä¸ä¸ªè¡¥ä¸ä¸ª"ï¼all æ¯"çæ´æ¹ææ ¢ç"
æ´ç´è§ç忹忳é¿è¿æ ·ï¼
for (let i = 0; i < tasks.length; i += limit) {
await Promise.all(tasks.slice(i, i + limit).map(t => t()));
}
é®é¢å¨è¾¹çï¼ä¸æ¹é 9 个快çè·å®ã1 ä¸ªæ ¢çè¿å¨è·ï¼è¿æ®µæ¶é´å¹¶åæå° 1ï¼æ¹æ¬¡åæ¢çç¬é´ï¼å¹¶åçè³çææå° 0ã100 个请æ±ãlimit 5ï¼å¦ææ¯æ¹ææ ¢çé£ä¸ªæ»æ¯ç¹å«æ ¢ï¼æ»èæ¶çº¦çäº"æ¯æ¹ææ ¢è ä¹å"ã
Promise.race æ¯ä»»ä½ä¸ä¸ªå®æå°±å¤éï¼ç«å»è¡¥ä½ï¼å¹¶åæ²çº¿è´´ç limit èµ°ãè¿æ¯"å¨æè¡¥ä½"å"åæ¹"çå·®å«ââAI æ¿ä½ éäºå¯¹çé£ä¸ªï¼ä½ä½ è¦æ¯ä¸æä¸ºä»ä¹å¯¹ï¼ä¸æ¬¡æ¹ä»£ç æ¶ä½ å°±ä¸ç¥éè¿ä¸¤ä¸ªé该éåªä¸ªã
è¯ä¹äºï¼executing éåçæ¯"æ¸ ç promise"
注æ const e = p.then(...) è¿ä¸è¡ï¼æ¨è¿æ°ç»çæ¯ eï¼ä¸æ¯ pã
å·®å«å¨ä¸ä¸ªæ¶åºä¿è¯ï¼e è¦å¨ splice æ§è¡å®ä¹åæ resolveãæä»¥ Promise.race(executing) å¤éçé£ä¸å»ï¼åé¢å·²ç»éæ¾å®äºï¼è¡¥ä¸ä¸ä¸ªä»»å¡ä¸å®ä¸ä¼è¶
éã
妿åçæ¯ pï¼race å¤éçé£ä¸å»ï¼æ¸ çç微任å¡å¯è½è¿æ²¡æ§è¡ï¼"ç°å¨è¡¥ä¸ä¸ªä¼ä¸ä¼è¶ é"å°±å¾é äººèæ¨å¾®ä»»å¡é¡ºåºæ¥ç¡®è®¤ãç»å¤§å¤æ°æ¶åç»æä¸æ ·ï¼ä½ä»£ä»·æ¯ï¼ä»»ä½å¨ review è¿æ®µä»£ç ç人ï¼é½å¾å å¨èåéèµä¸æ¬¡å¾®ä»»å¡é¡ºåºãå eï¼æ¯æ"race è¿å = åé¢å·²éæ¾"åæä¸éè¦æ¨ççä¸åéãè¿æ¯"è½è·"å"è·å¾æç½"ä¹é´çåæ°´å²ã
è¯ä¹ä¸ï¼å¤±è´¥ä¸æ¯æ¥éï¼æ¯ç§æ± å
è¿æ¯ææåºå¹¸å¨æåæ¶åç°ãè䏿¯å¨çº¿ä¸åç°çä¸ä¸ªã
å设æä¸ªä»»å¡ reject äºãp ä¼ rejectï¼é£ e å¢ï¼p.then(onFulfilled) ä¸æè·æç»ï¼e ä¼åæ · rejectï¼splice æ°¸è¿ä¸æ§è¡ã
è¿éååºï¼
- å½åè¿æ¬¡
Promise.race(executing)ç«å» rejectï¼è°ç¨æ¹æ¿å°é误ââè¿ä¸æ¥è¿ç®ç¬¦åé¢æï¼ - ä½é£ä¸ª e æ°¸è¿çå¨ executing éï¼å颿°¸ä¹ ç§æä¸ä¸ªï¼
- ä¹åæ¯ä¸ªæ°ä»»å¡è¿æ¥ï¼é½çå°
executing.length >= limitï¼é½å» await raceï¼è race ä¼å¨é£ä¸ªå·² reject ç e ä¸ç«å» rejectââæ± åä»è¿ä¸å»èµ·æ°¸ä¹ æåï¼åç»ææä»»å¡è¿æ¥å³æéã
䏿¬¡å¤±è´¥ï¼å ¨åéªè¬ãåæµæµä¸åºæ¥ï¼å ä¸ºåæµç happy path ä¸å失败ç¨ä¾ï¼èçå®ä¸ççæ¥å£ï¼æ¯ä¸å®ä¼å¤±è´¥çã
æéåççæ¬
æåä¹åï¼ææå®æ¹æäº"计æ°å³çç¸ãfinally ä¿è¯éæ¾"çåæ³ï¼
class RequestPool {
private running = 0;
private queue: Array<() => void> = [];
constructor(private limit: number) {}
async run<T>(task: () => Promise<T>): Promise<T> {
if (this.running >= this.limit) {
await new Promise<void>(r => this.queue.push(r));
}
this.running++;
try {
return await task();
} finally {
this.running--;
this.queue.shift()?.();
}
}
}
æ¹å¨ä¸å¤ï¼
- ç¨æ°å计æ°
runningä»£æ¿æ°ç»ï¼"åä»ä¹"çé®é¢ç´æ¥æ¶å¤±ï¼ - åé¢éæ¾æ¾è¿
finallyï¼å¤±è´¥ä¹éæ¾ãéåç §å¸¸åè¿ï¼æ± åä¸ä¼è¢«ç§ç©¿ï¼ - éè¯¯åæ ·æç»è°ç¨æ¹ï¼æ± åä¸åéââå个任å¡çé离æ¯è°ç¨æ¹çäºï¼å ä¸å± catch å°±è¡ã
è³äºåæ¶ï¼æ± ååªç®¡"éåéçä¸åäº"ï¼ç»ä»¶å¸è½½æ¶æ¸
空éåå¹¶ rejectï¼ï¼å¨é请æ±è¦æ AbortController.signal ä¼ è¿ fetchãè¿é¨åä¸å±äºæ± åãå±äºä¸å¡ï¼ä½ AI ççæ¬éå¸¸ä¸¤æ ·é½ä¸åââå®é»è®¤ä½ ç鿱鿲¡æ"åæ¶"è¿ä¸ªè¯ã
ä½ åæ»çå¹¶åæ°ï¼å¤§æ¦çæ¯éç
AI åçå¹¶åæ§å¶å¨ï¼limit å ä¹é½æ¯åæ»ç 3ã5 æ 10ã使£ç¡®ç并忰䏿¯å¸¸æ°ï¼å®åå³äºèµæºï¼
- API 请æ±ï¼3-6ãæµè§å¨ååè¿æ¥ä¸éæ¬æ¥å°±æ¯ 6ï¼ä½ çæ± åå¼ 10ï¼å¤åºæ¥çåªæ¯å¨æµè§å¨å±æéï¼limit çäºè£ 饰åï¼
- å¾ççéæèµæºï¼6-10ï¼èµ°çæ¯å¦ä¸ä¸ªåçè¿æ¥æ± ï¼ä¸æ¢ API çä½ï¼
- ä¸ä¼ /大 bodyï¼1-2ï¼ç¶é¢å¨ä¸è¡å¸¦å®½ï¼å¹¶åè¶å¤å¤§å®¶è¶æ ¢ã
è¿æç½ç»ç¯å¢ï¼åå ¬å®¤ Wi-Fi ä¸èæç 6ï¼å¨å°éå¼±ç½ä¸å°±æ¯è¶ æ¶é£æ´ã认çåçè¯ï¼limit åºè¯¥è·çç½ç»è´¨éèµ°ï¼è³å°ï¼æå®åæå¯é åæ°ï¼è䏿¯å¸¸éã
éè¯ä¹ä¸æ ·ã"失败ç«å»éè¯"åå¹¶åä¸éå å¨ä¸èµ·å°±æ¯æµé飿´ââåºéçç¬é´ï¼éè¯è¯·æ±ç«å»éæ°å ä½ï¼çäºèªå·±æèªå·±ãæ£ç¡®å§¿å¿æ¯ææ°éé¿ + éè¯æ¬¡æ°ä¸éï¼èä¸éè¯è¦éæ°è¿æ± åæéï¼ä¸è½ç»å¼æ± åç´æ¥åã
å¹¶åæ§å¶èªæ£éæ¥è¡¨
åå»ç¿»ä½ 项ç®é AI åç弿¥ä»£ç ï¼å¯¹çè¿å¼ 表é®ï¼
| é®èªå·± | AI 常è§åæ³ | é£é© | æ¹æ³ |
|---|---|---|---|
| å¹¶åæä¹è¡¥ä½ï¼ | åæ¹ chunk + all | æ¹è¾¹çå¹¶åå½ 0ï¼æ´æ¹è¢«ææ ¢çææ» | race å¨æè¡¥ä½ï¼æè®¡æ°+éå |
| åé¢ç¶æåä»ä¹ï¼ | æ°ç»åä»»å¡ promise | æ£ç¡®æ§è¦é èµå¾®ä»»å¡é¡ºåºç¡®è®¤ | 忏 ç promiseï¼æå¹²èç¨è®¡æ° |
| ä¸ä¸ªå¤±è´¥ä¼ææ ·ï¼ | race ç´æ¥ reject | å颿°¸ä¹ ç§æï¼åç»å ¨å峿 | finally éæ¾ï¼è°ç¨æ¹éä»»å¡é离 |
| è½ä¸è½åæ¶ï¼ | å®å ¨ä¸æ¯æ | 页é¢å¸è½½å请æ±è¿å¨é£ | AbortController ä¼ ä¿¡å· + æ¸ éå |
| å¹¶åæ°æä¹å®ï¼ | åæ» 3 / 5 / 10 | å¼±ç½ 10 å¹¶å = è¶ æ¶é£æ´ | æèµæºå®ï¼API 3-6ï¼å¾ç 6-10ï¼ä¸ä¼ 1-2 |
| éè¯æä¹åï¼ | 失败ç«å»éè¯ | å¹¶åä¸é + ç«å»éè¯ = æµé飿´ | ææ°éé¿ + éè¯æ¬¡æ°ä¸é |
å卿å
AI åç代ç ï¼å¯ä»¥ä¿¡å®è·ï¼ä½ä¸è½ä¿¡å®æã
è·æ¯å®çèè´£ï¼ææ¯ä½ çãå 为线ä¸çåºäºçæ¶åï¼æä½ ç䏿¯"æç¨è¿"ï¼èæ¯"æè®²å¾æ¸ "ã
åå»å¯¹ç项ç®é飿®µå¼æ¥ä»£ç é®èªå·±ä¸ä¸ªé®é¢ï¼æä¹è¡¥ä½ãå¤±è´¥ä¼ææ ·ãè½ä¸è½åæ¶ã
çä¸ä¸æ¥çè¯ï¼æåä¸éãå¼å¾çã
Aitishiku.com