Aynı anda en fazla N görevin çalıştığı bir Promise havuzu (concurrency limit) yazın.
Cevap
Promise.all tüm görevleri aynı anda başlatır; 1000 dosya yüklerken bu tarayıcıyı ve sunucuyu boğar. Çözüm, sabit sayıda "worker" başlatıp her birinin sıradaki görevi kuyruktan almasıdır.
async function runWithLimit(tasks, limit) {
const results = new Array(tasks.length);
let next = 0;
async function worker() {
while (next < tasks.length) {
const index = next++; // JS tek thread: yarış durumu yok
results[index] = await tasks[index]();
}
}
const workers = Array.from({ length: Math.min(limit, tasks.length) }, worker);
await Promise.all(workers);
return results; // sonuçlar orijinal sırada
}
// Kullanım: görevler fonksiyon olmalı, Promise değil
const urls = ["/a", "/b", "/c", "/d", "/e"];
const tasks = urls.map((u) => () => fetch(u).then((r) => r.json()));
const data = await runWithLimit(tasks, 2);Neden görevler fonksiyon?
Bir Promise oluşturulduğu anda çalışmaya başlar. fetch(u) dizisi verseydik limit anlamsız olurdu; bu yüzden lazy başlatılan fonksiyonlar (thunk) veriyoruz.
Follow-up'lar
- Hata davranışı: Yukarıdaki kod
Promise.allgibi ilk hatada reddeder, ama diğer worker'lar çalışmaya devam eder.allSettledbenzeri davranış için her görevitry/catchile sarıp{status, value/reason}saklayın. - İptal:
AbortSignalile kuyruğu durdurma. - Hazır kütüphaneler:
p-limit,p-map.
İlgili JavaScript soruları
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.