Best Studio 1
Best Studio
TuZaKK 1
TuZaKK
Mt2Hizmet 1
Mt2Hizmet
Agora Metin2 1
Agora Metin2
Bvural41 1
Bvural41
kaptanmikro1 1
kaptanmikro1
R 1
Roksam
[DEV]AB 1
[DEV]AB
Sevdamsın 1
Sevdamsın
farkmt2official 1
farkmt2official
emirhanHCL 1
emirhanHCL
Scarlet 1
Scarlet
Hikaye Ekle

[NODE JS] Promise.all ile Paralel Islemler

  • Konuyu başlatan Konuyu başlatan Silverhand
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 1
  • Görüntüleme Görüntüleme 9

Türkiye'de ilk Mobil & PC Aynı Anda Metin2 Oyna. Triarchonline kalıcı ve uzun ömürlü yapısı ile 24 Temmuz'da açılıyor. | 1-99 Mobil Metin2 Triarch HEMEN TIKLA!

nodejs.png


[NODE JS] Promise.all ile Paralel Islemler​


Selam arkadaslar, bugun asenkron programlamanin en guclu aracindan biri olan Promise.all'i inceleyecegiz. Birden fazla bagimsiz asenkron islemi ayni anda baslatip hepsinin bitmesini beklemek istediginizde Promise.all tam ihtiyaciniz olan sey. Ben bu fonksiyonu neredeyse her projemde kullaniyorum ve performans kazanimi inanilmaz oluyor.

Promise.all Nasil Calisir?​


Promise.all bir Promise dizisi alir ve tum Promise'ler resolve oldugunda tek bir Promise olarak resolve olur. Sonuc, her Promise'in sonucunu iceren bir dizidir ve dizi sirasi, verilen Promise'lerin sirasini korur. Ama eger dizideki herhangi bir Promise reject olursa, Promise.all hemen reject olur ve diger Promise'lerin sonuclarini yok sayar. Buna "fail-fast" davranis denir.

Bunu suna benzetebilirsiniz: bir restoranda 5 kisi yemek siparis veriyor. Garson hepsinin siparisini ayni anda mutfaga iletiyor. Tum yemekler hazir oldugunda masaya getiriliyor. Ama birinin siparisi iptal edilirse, tum siparis iptal sayiliyor. Biraz sert bir yaklasim ama transaction benzeri islemlerde cok mantikli.

JavaScript:
// Temel Promise.all kullanimi
const p1 = new Promise(resolve => setTimeout(() => resolve('A'), 300));
const p2 = new Promise(resolve => setTimeout(() => resolve('B'), 100));
const p3 = new Promise(resolve => setTimeout(() => resolve('C'), 200));

Promise.all([p1, p2, p3])
    .then(sonuclar => {
        console.log(sonuclar); // ['A', 'B', 'C'] - sira korunur!
        // p2 en once bitmesine ragmen sira degismez
    });

// Hata durumu - fail-fast
const p4 = new Promise(resolve => setTimeout(() => resolve('OK'), 300));
const p5 = new Promise((_, reject) => setTimeout(() => reject(new Error('HATA!')), 100));
const p6 = new Promise(resolve => setTimeout(() => resolve('OK'), 200));

Promise.all([p4, p5, p6])
    .then(sonuclar => {
        console.log('Bu calisMAZ');
    })
    .catch(hata => {
        console.error('Yakalanan hata:', hata.message); // HATA!
    });

Gercek Hayat Ornekleri​


Promise.all'in en yaygin kullanim alanlari sunlar: birden fazla API'den veri cekmek, birden fazla dosyayi ayni anda okumak, veritabaninda paralel sorgular calistirmak ve sayfa icin gerekli tum verileri ayni anda yuklemek. Asagida gercekci ornekler haziladim.

JavaScript:
const fs = require('fs/promises');
const path = require('path');

// Ornek 1: Birden fazla dosyayi paralel okuma
async function cokluDosyaOku(dosyaYollari) {
    const baslangic = Date.now();

    const sonuclar = await Promise.all(
        dosyaYollari.map(async yol => {
            const icerik = await fs.readFile(yol, 'utf8');
            return { yol: path.basename(yol), boyut: icerik.length };
        })
    );

    const sure = Date.now() - baslangic;
    console.log(`${sonuclar.length} dosya ${sure}ms'de okundu`);
    sonuclar.forEach(s => console.log(`  ${s.yol}: ${s.boyut} karakter`));

    return sonuclar;
}

// Ornek 2: Dashboard verisi toplama
async function dashboardVerisiTopla(kullaniciId) {
    const baslangic = Date.now();

    // Tum verileri paralel olarak al
    const [profil, siparisler, bildirimler, istatistikler] = await Promise.all([
        profilGetir(kullaniciId),
        siparisleriGetir(kullaniciId),
        bildirimleriGetir(kullaniciId),
        istatistikleriGetir(kullaniciId)
    ]);

    const sure = Date.now() - baslangic;
    console.log(`Dashboard verisi ${sure}ms'de toplandi`);

    return { profil, siparisler, bildirimler, istatistikler };
}

// Simule edilmis API fonksiyonlari
function profilGetir(id) {
    return new Promise(resolve => {
        setTimeout(() => resolve({ id, ad: 'Ahmet', uyelik: 'premium' }), 200);
    });
}

function siparisleriGetir(id) {
    return new Promise(resolve => {
        setTimeout(() => resolve([
            { id: 1, urun: 'Laptop', tutar: 15000 },
            { id: 2, urun: 'Mouse', tutar: 250 }
        ]), 300);
    });
}

function bildirimleriGetir(id) {
    return new Promise(resolve => {
        setTimeout(() => resolve([
            { mesaj: 'Sipaarisiniz kargoda', okundu: false },
            { mesaj: 'Yeni kampanya', okundu: true }
        ]), 150);
    });
}

function istatistikleriGetir(id) {
    return new Promise(resolve => {
        setTimeout(() => resolve({
            toplamSiparis: 45, toplamHarcama: 25000, sonGiris: '2024-07-10'
        }), 250);
    });
}

// Ornek 3: Rate limiting ile toplu islem
async function topluIslem(elemanlar, islemFn, esZamanliLimit = 5) {
    const sonuclar = [];

    for (let i = 0; i < elemanlar.length; i += esZamanliLimit) {
        const grup = elemanlar.slice(i, i + esZamanliLimit);
        console.log(`Grup ${Math.floor(i / esZamanliLimit) + 1} isleniyor (${grup.length} eleman)...`);

        const grupSonuclari = await Promise.all(
            grup.map(eleman => islemFn(eleman))
        );

        sonuclar.push(...grupSonuclari);
    }

    return sonuclar;
}

// Kullanim
async function main() {
    // 20 elemani 5'erli gruplar halinde isle
    const elemanlar = Array.from({ length: 20 }, (_, i) => i + 1);

    const sonuclar = await topluIslem(
        elemanlar,
        async (eleman) => {
            await new Promise(r => setTimeout(r, 100));
            return eleman * 2;
        },
        5
    );

    console.log('Sonuclar:', sonuclar);
}

main().catch(console.error);

Dikkat Edilmesi Gerekenler​


Promise.all kullanirken birkac konuda dikkatli olmalisiniz. Birincisi, fail-fast davranisi. Eger tum sonuclari almak istiyorsaniz, bir tanesi basarisiz olsa bile, Promise.allSettled kullanin ki bir sonraki konumuz bu. Ikincisi, cok fazla paralel islem baslatmak sistem kaynaklarini tuketebilir. 1000 tane paralel HTTP istegi gondermek sunucunuzu ve hedef sunucuyu yorabilir. Bu yuzden batch halinde islem yapmayi dusunun.

Ucuncusu, Promise.all bos dizi alirsa hemen bos diziyle resolve olur, bu bir hata degildir. Dorduncusu, dizideki elemanlardan biri Promise degilse, otomatik olarak Promise.resolve ile sarilir. Yani Promise.all([1, 2, 3]) yazsaniz bile calisir ve [1, 2, 3] dondurur. Ha son bir sey daha: sira garanti edilir ama calisma sirasi garanti edilmez. Yani sonuc dizisinde ilk eleman her zaman ilk Promise'in sonucudur ama o Promise en son bitebilir. Neyse, Promise.allSettled konusunda gorusmek uzere!
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst