CodeBlanks Logo Icon CodeBlanks

Eş zamanlılık kontrolü

JavaScript kursu · İleri seviye · Ders 76/100

Aynı anda kaç işlem çalışacağını sınırlayarak batch işleme yapmayı öğrenirsin.

Eş zamanlılık kontrolü

Binlerce async görevin var (örneğin 1000 API çağrısı). Hepsini aynı anda başlatmak sunucuyu yorar, hız sınırına (rate limit) takılır ya da bağlantı tükenmesine yol açar. Eş zamanlılık kontrolü, aynı anda yalnızca N işin çalışmasına izin verir; diğerleri sıra bekler.

// 1000 çağrı = kötü fikir
await Promise.all(urls.map(fetch));
// 2'şerli gruplar = güvenli

Bu yaklaşım, throughput'u yüksek tutarken sunucu yükünü öngörülebilir tutar.

Havuz (pool) deseni

Eş zamanlılık için yaygın bir desen havuz desenidir: N iş aynı anda çalışır; biri bitince sıradaki başlatılır. Bu, bir kuyruk (queue) ve çalışan (worker) mantığı kurar.

async function pool(tasks, limit) {
  const results = [];
  for (let i = 0; i < tasks.length; i = i + limit) {
    const batch = tasks.slice(i, i + limit);
    const out = await Promise.all(batch.map(t => t()));
    results.push(...out);
  }
  return results;
}

Bu basit sürüm, görevleri limit büyüklüğünde gruplara böler ve her grubu sırayla çalıştırır.

Uygulama Toplu işleme fonksiyonu

runBatch(tasks, limit) adında bir async fonksiyon yaz. results adında boş bir dizi oluştur. tasks dizisini limit büyüklüğünde gruplara böl: for döngüsü ile i'yi limit kadar artır ve tasks.slice(i, i + limit) ile bir grup al. Her grubu Promise.all ile birlikte çalıştır (batch.map(t => t())); sonuçları results.push(...out) ile ekle. En son results'u döndür. Test için [1, 2, 3, 4, 5] dizisinden her sayıyı ikiyle çarpan task'ler oluştur, runBatch(tasks, 2) çağrısının sonucunu console.log ile yazdır.

Örnek çözümü göster
async function runBatch(tasks, limit) {
  const results = [];
  for (let i = 0; i < tasks.length; i = i + limit) {
    const batch = tasks.slice(i, i + limit);
    const out = await Promise.all(batch.map(t => t()));
    results.push(...out);
  }
  return results;
}
const tasks = [1, 2, 3, 4, 5].map(n => () => Promise.resolve(n * 2));
runBatch(tasks, 2).then(r => console.log(r));

Kendini test et

  1. 1000 API çağrısı var. Neden Promise.all ile hepsini aynı anda başlatmak kötü olur?

    • Sunucu hız sınırına takılabilir ya da bağlantı tıkanır
    • Promise.all yavaş çalışır
    • Promise.all 1000'den fazla çağrı desteklemez
    • JavaScript bunu otomatik sınırlandırır
    Cevabı göster

    Sunucu hız sınırına takılabilir ya da bağlantı tıkanır — Doğru! Çok fazla eş zamanlı istek hız sınırına ya da bağlantı tükenmesine yol açar.

  2. Eş zamanlılık sınırını belirle

    const LIMIT = ____;
    async function pool(tasks) {
      const results = [];
      for (const task of tasks.slice(0, LIMIT)) {
        results.push(await task());
      }
      return results;
    }
    Cevabı göster
    const LIMIT = 3;
    async function pool(tasks) {
      const results = [];
      for (const task of tasks.slice(0, LIMIT)) {
        results.push(await task());
      }
      return results;
    }
  3. Eş zamanlılık kavramlarını eşleştir

    batch
    küçük gruplar
    pool
    N iş aynı anda
    rate limit
    hız sınırı
    queue
    sıradaki iş

İleri seviye bölümündeki tüm dersler