dersblog

Javascript Fetch, Paralellik, Kapsam İsteği (Range Request)

Çok sayıda URL bağlantısının verisini paralel şekilde almak gerekebilir. Fakat tüm URL'lerin hepsi bitmesini beklemek gerekiyorsa, yani URL kümesi içinde asenkron ama tüm işin bitmesini beklemek senkron olmak gerektiriyorsa, Javascript'in await ve Promise.all kavramlarını bilmek gerekecek.

İki tane basit URL ile başlayalım, bunlar Github'da olan düz metin dosyaları,

const fetchURLs = async (urls) => {

    var promises = urls.map(url => fetch(url));

    const responses = await Promise.all(promises);

    const data = await Promise.all( responses.map(response => response.text()) );

    return data;

    console.log('done')

}

async function init() {

    const urls = ['https://raw.githubusercontent.com/tj/histo/master/examples/small.txt',
                  'https://raw.githubusercontent.com/tj/histo/master/examples/medium.txt'];
    console.log('start');
    var res = await fetchURLs(urls);
    console.log('end');

    console.log(res);
}

Üstteki olanları açıklarsak, promises listesine fonksiyon objeleri ekledik, o liste üzerinde await Promise.all işleterek tüm işin bitmesini bekliyoruz. Yanlız dikkat, await kullanan her fonksiyonun kendisi de asenkron olmak zorundadır, fetchURLs fonksiyonu bu sebeple async olarak işaretlendi, fakat Web sayfa ortamında bu problem değil, belki bir düğme tıklanıp üstteki çağrıyı tetiklemiştik, kullanıcı zaten sonucu bekleyecektir, iş bitince sonuçlar asenkron şekilde sayfada gösterilir, bu kullanım kullanıcı / sayfa iletişimi ile uyumludur.

Bir örnek daha: [1] yazısında kapsam istekleri ile Web ortamında büyük veri dosyalarının tamamını indirmeden "nokta okuyuş" ile azar azar parçalarını okuyabildiğimizi gördük. GLOBE verisi tam bu tür okumaya uygundur, dünya kordinatları direk dosya içinde indislere tercüme edilebilir, ve bu indislere nokta atışı ile gidip o kordinatın verisi alınabilir.

İki tane indise fetch erişimini altta görüyoruz, bu kod aynı şekilde paralel işletim, senkron bekleme ve ek olarak GLOBE için gereken arrayBuffer ve Uint16Array kullanımlarını gösteriyor.

async function init() {

    var url = "/vs/vs/data/g10g";

    var promises = [];

    promises.push(
        fetch(url, {
            headers: {
                'content-type': 'multipart/byteranges',
                'range': 'bytes=33681360-33681361',
            },
        })
    );

    promises.push(
        fetch(url, {
            headers: {
                'content-type': 'multipart/byteranges',
                'range': 'bytes=33681362-33681363',
            },
        })
    );

    const responses = await Promise.all(promises);

    const data1 = await Promise.all( responses.map(response => response.arrayBuffer() ));

    const data2 = await Promise.all( data1.map(response => new Uint16Array(response) ));

    data2.forEach(function(x) {
        console.log(x[0]);
    });

}

Kaynaklar

[1] Yükseklik (Elevation) Verileri


Yukarı