JS Nesneleriyle Asenkron Programlama: Promise ve Async/Await Kullanarak Event-driven Sistemler İnşa Etmek kitabı, Javascript'te asenkron programlama konusunda derinlemesine bir kılavuz sağlar Etkin bir kodlama yaklaşımı olan Promise ve Async/Await kullanarak etkin bir şekilde event-driven sistemler inşa edebilirsiniz Bu kitap, başlangıçtan ileri seviyeye kadar tüm JS geliştiricileri ve öğrencileri için mükemmel bir kaynak

JavaScript, asenkron programlama mantığına dayalı olarak geliştirilen bir programlama dilidir. Asenkron programlama, bir işlemin tamamlanmasını beklemek yerine, işlemin tamamlanması için gereken işlemleri sırayla yaparak, işlem tamamlandığında sonuçları kullanmaya izin verir.
JavaScript'te, asenkron programlama için Promise ve Async/Await kullanılır. Promise nesneleri, işlemleri çözmek için gereken bir nesnedir. Callback fonksiyonlara göre avantajları nelerdir? Promise zincirleme, Promise.all, Promise.race ve Async/Await'in kullanımı anlatılacak. Bu yöntemler, event-driven sistemlerin inşa edilmesinde çok önemlidir. Event-driven sistemler, bir olayın oluştuğu anda işleme başlayan ve sürekli olarak kullanıcı girdilerine yanıt veren sistemlerdir. Promise ve Async/Await, event-driven sistemlerin geliştirilmesinde kod okunurluğunu artıran ve daha az hata ile daha verimli bir kod yazmanıza yardımcı olan önemli araçlardır.
Asenkron Programlama
Asenkron programlama, bir işlemin tamamlanması beklenirken diğer işlemlerin de bu süre zarfında çalışmasına olanak tanıyan bir programlama tekniğidir. Bu sayede program, işlem süresince donmaz ve kullanıcıya daha iyi bir deneyim sunar. JavaScript'te ise asenkron programlama, event-driven sistemlerin inşa edilmesinde oldukça önemlidir. Bunun sebebi JavaScript'in tek başına işlem yapmasıyla birlikte, birçok işlemi de eş zamanlı olarak yapabilmesidir. Bu sayede program daha hızlı ve verimli çalışır.
Asenkron programlama tekniklerinin kullanıldığı bir uygulama örneği de Promise nesneleridir. Callback fonksiyonların yerine Promise nesneleri kullanılarak kodun daha okunaklı hale gelmesi sağlanır. Promise nesneleri, bir işlemin başarıyla tamamlanması durumunda verilen bir değeri işlemesi ve başarısız olması durumunda da hata mesajını verdikten sonra yine işlemini sonlandırması prensibine dayanır.
- Asenkron programlama, işlem süresince donmayan programlar için büyük bir önem taşır.
- JavaScript'in eş zamanlı birçok işlem yapabilme özelliği sayesinde asenkron programlama daha verimli ve hızlı çalışan programlar için idealdir.
- Promise nesneleri, callback fonksiyonları yerine kullanılarak daha okunaklı kod yazımı ve işleme başarı ve hata mesajları için bir anlaşma sağlar.
Promise Nesneleri
Promise nesneleri, JavaScript ile asenkron programlamada kullanılan bir yapıdır. Bir işlemin tamamlanması için beklenen bir fonksiyon objesi olarak düşünülebilir. Promise nesnesi içinde, işlem tamamlandığında geri döndürülecek olan sonuç (resolve) veya hata (reject) fonksiyonları belirtilir. Bu sayede, asenkron bir işlem sonucunda oluşabilecek hataların yönetimi kolaylaşır.
Promise nesnelerinin kullanımı, callback fonksiyonlarının kullanımına göre birçok avantaja sahiptir. Öncelikle, daha okunaklı ve anlaşılır bir kod yazmak mümkündür. Ayrıca, Promise zincirleme sayesinde, aynı anda birden fazla işlem gerçekleştirmek daha kolay hale gelir. Promise nesneleri, aynı zamanda Promise.all() ve Promise.race() fonksiyonlarıyla birçok işlemi eş zamanlı veya sırayla gerçekleştirmek için kullanılabilir.
Promise.all() | Promise.race() |
---|---|
Bir dizi Promise nesnesi alır ve bütün işlemlerin tamamlanması beklenir. İşlemlerden biri bile hata döndürürse, tüm işlemlerin reject edilmesini sağlar. | Bir dizi Promise nesnesi alır ve ilk tamamlanan işlemin sonucunu resolve eder. |
Promise nesnelerinin kullanımı, asenkron programlamada kod okunurluğunu ve yönetimini önemli ölçüde artırmaktadır.
Promise Zincirleme
Promise zincirleme, birden fazla Promise nesnesinin birbirlerine bağlanarak ve ardışık olarak çalıştırılmasıdır. Bu yöntem, asynchronous kodun okunabilirliğini ve anlaşılabilirliğini artırır.
Promise zincirleme söz dizimi, ardışık Promise nesnelerini then() fonksiyonlarıyla birleştirerek oluşturulur. then() fonksiyonu, bir önceki Promise nesnesinin sonuç değerini parametre olarak alır ve yeni bir Promise nesnesi döndürür.
Örnek Promise Zincirleme Kodu: |
---|
|
Bu kod, bir API'den veri alır, bu verileri işler ve son olarak işlenmiş verileri ekranda gösterir. Her then() fonksiyonu, bir önceki Promise nesnesinin sonucunu alır ve yeni bir Promise nesnesi döndürür.
Bu yöntem, Promise'leri callback fonksiyonlarına göre daha kolay bir şekilde birleştirebilir ve asenkron kodun okunabilirliğini artırabilir. Ancak, çok uzun zincirler oluşturmak, daha karmaşık hale gelebilir ve hataların bulunması ve izlenmesi zorlaşabilir.
Promise.all
Promise.all, birden çok Promise nesnesini birleştirerek tek bir Promise nesnesi oluşturur ve bu, tüm Promise nesnelerinin tamamlanması gerektiğinde gerçekleştirilir. Promise.barikat() gibi birçok Promise nesnesini bir arada çalıştırırken yararlı olabilir. Böylece, birden çok işlemi bir arada çalıştırarak, kodunuzun daha hızlı bir şekilde çalışmasını sağlayabilirsiniz.
Promise.all, bir liste şeklinde gelen Promise nesnelerini parametre olarak alabilir ve eş zamanlı olarak çalıştırabilir. Bu şekilde, devam eden işlemlerde herhangi bir gecikme olmadan birden çok işlemi aynı anda gerçekleştirebilirsiniz. Promise.all kullanırken, tüm işlemlerin tamamlanması beklenir ve tamamlandığında tek bir sonuç döndürülür. Bu, işlemlerin sırasına karışmaması için de önemlidir.
Promise.all kullanımı: |
---|
Promise.all([ promise1, promise2, promise3]).then(result => { console.log(result);}).catch(error => { console.log(error);}); |
Yukarıdaki örnekte, Promise.all, promise1, promise2 ve promise3 nesnelerini birleştirerek bir dizi oluşturur. Tüm işlemler tamamlandığında, tek bir sonuç döndürülür ve sonuç, 'then()' yöntemi kullanarak alınır. Eğer herhangi bir işlem hata alırsa, Promise.all bunu 'catch()' yöntemi ile yakalar ve hata mesajını gösterir. Promise.all, birden fazla Promise nesnesi ile kullanıldığında kod okunabilirliğini artırır ve daha ölçeklenebilir bir kod yazımı sağlar.
Promise Race
Promise.race(), birden fazla promise nesnesi verildiğinde, sadece ilk sonuç dönen promise nesnesini döndürür. Bu işlev, birden fazla API'yi istek yapmanız gerektiğinde ya da birkaç işlevi tek seferde çalıştırmanız gerektiğinde faydalıdır.
Örneğin, bir REST API'ye istek yapıyorsanız ve farklı sunucular üzerinde daha hızlı yanıt veren çeşitli alternatifleriniz varsa, Promise.race() işlevi bu alternatifleri test etmek ve en hızlı yanıtı seçmek için kullanılabilir.
Promise.race() işlevi, birden fazla Promise nesnesi alır ve bu nesnelerin herhangi biri tamamlanana kadar bekler. Daha sonra, tamamlanan Promise nesnesinin sonucunu döndürür. Bu işlev aynı zamanda birden fazla Promise zincirinde de kullanılabilir ve kod okunurluğunu artırır.
Aşağıdaki örnek, içerisinde bulunan iki Promise nesnesi arasından, hangi promise nesnesinin daha önce döneceğini belirlemek için Promise.race() işlevini kullanır:
const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Promise 1 bitti'); }, 2000);});const promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Promise 2 bitti'); }, 1000);});Promise.race([promise1, promise2]).then(result => { console.log(result); // "Promise 2 bitti"});
Yukarıdaki kod, Promise.race() işlevi ile iki Promise nesnesini yarattı ve her biri, belirtilen süre sonunda "Bitti" döndürdü. Promise.race() işlevi, bu Promise nesnelerinin herhangi biri tamamlandığında çalışır ve ilk tamamlananın sonucunu döndürür. Yukarıdaki örnekte, promise2 daha kısa sürede tamamlandığından, sonucu döndürür ve "Promise 2 bitti" sonucunu verir.
Async/Await
Async/Await, JavaScript'in son zamanlarda geliştirilen bir özelliği olarak karşımıza çıkmaktadır. Promise'lere kıyasla daha kolay bir okunabilirliğe sahip olan bu özellik, asenkron fonksiyonları beklemesini sağlar.
Bunun avantajları arasında, kod okunabilirliğinin artması, Promise zincirleme yapabilmek yerine, daha sade bir syntax kullanmak ve hata yakalama işleminin daha kolay hale getirilmesi yer alır.
Async/Await, kullanımı oldukça kolaydır. Async anahtar kelimesini fonksiyonun başına ekledikten sonra, işlem süresince beklenmesini istediğimiz yerde Await anahtar kelimesini kullanırız. Bu sayede, işlem bittikten sonra geriye bir değer döndürür ve bu değer farklı işlemlerde kullanılabilir.
Bir diğer avantajı ise, hata yakalama işlemini kolaylaştırmasıdır. Promise'lerde hata yakalamak için try-catch yapısı kullanılırken, Async/Await yapısında ise try-catch blokları otomatik olarak eklenir.
Syntax açısından ise, Async anahtar kelimesi fonksiyonun başında belirtilirken, Await anahtar kelimesi ise işlem yapılmak istenen promise nesnesi için kullanılır. Bu sayede, kodun okunabilirliği daha kolay bir hale gelir.
Async Fonksiyonlar
Async fonksiyonları, function anahtar kelimesinin önüne async keyword'ü eklenerek tanımlanır. Bu fonksiyonlar, içlerinde await keyword'üne sahip Promise nesnelerini kullanarak, JavaScript kodu içinde sinkron olmayan işlemleri gerçekleştirebilir.
Bu fonksiyonlar özellikle, sunucu ve benzeri işlemlerde kullanılır. Bu işlemler, işlemcinin yoğun bir şekilde çalışması gerektiği için, işlem sırayla devam eder ve uzun bir bekleme süresi gerektirir. Async fonksiyonları kullanarak, bu işlemler paralel olarak gerçekleştirilebilir ve işlem süresi önemli ölçüde azaltılabilir.
Async fonksiyonlar, her zaman Promise objesi döndürür. Bu obje, bir hata durumunda hata mesajını içeren reject metodu ve işlem başarıyla tamamlandığında işlemin sonucunu içeren resolve metodu içerir. Bu sayede, Promise nesnesinin avantajlarından faydalanarak hata ayıklama ve işlemin takibi kolay hale getirilir.
Await Operatörü
Await operatörü, bir fonksiyonun içindeki Promise nesnesinin tamamlanmasını bekler ve bu işlem sırasında diğer kod bloklarının çalışmasını duraklatır. Birçok asenkron işlemi uygun sıraya sokmak için kullanılır.
Await operatörünün kullanımı oldukça basittir. Bir fonksiyonun başına async anahtar kelimesi konulur. Bu async anahtar kelimesi, fonksiyonun içinde Promise nesnelerinin kullanılacağını ve kendisinin de asenkron bir fonksiyon olduğunu belirtir. Ardından, bekleme işlemi gereken Promise nesnesi üzerinde await anahtar kelimesi kullanılır. Bu sayede, Promise tamamlandığında, await işlemi başarıyla tamamlanır ve fonksiyon devam eder.
Örneğin, bir API çağrısı yapmak Promise nesnesi döndürür. Bu Promise nesnesi üzerinde, verileri bekletir ve uygun zamanda işleyebilirsiniz. Bunun için gerekli kodlar aşağıdaki gibidir:
async function getData() { try { const response = await fetch('data.json'); const data = await response.json(); console.log(data); } catch(error) { console.error(error); }}
Buradaki fetch işlemi Promise nesnesi döndürür. Bu Promise nesnesi üzerinde await anahtar kelimesi kullanarak, verilerin tamamen indirilmesini bekleyebilir ve uygun zamanda kullanabilirsiniz. Böylece, programın akışı da Promise nesnesinin tamamlanmasına göre yönlendirilir.
Await operatörü, birden fazla Promise nesnesiyle de kullanılabilir. Ancak, sadece bir tane await işlemi kullanarak, Promise nesnelerinin sıraya sokulması mümkündür. Bu sayede, işlemlerin daha okunaklı ve anlaşılır bir şekilde yazılması sağlanır.
Event-driven Sistemler İnşa Etmek
Event-driven sistemler, gerçek zamanlı uygulamalar için tasarlanan sistemlerdir. Bu sistemler, kullanıcı hareketlerine (mouse tıklamaları, klavye girişleri vb.) ve diğer sistem olaylarına (veri tabanı işlemleri, ağ istekleri vb.) tepki verirler. Event-driven sistemlerin iyi tasarlanması, sistem performansını ve kullanıcı deneyimini artırır.
Bu sistemlerin oluşturulması sırasında Promise ve Async/Await kullanılabilir. Promise'ler, geçiş süreçleri sırasında geri çağırımların kullanımını azaltır ve callback cehennemine düşmekten kurtuluruz. Async/Await ise Promise'lerin daha okunaklı bir şekilde kullanılmasını sağlar.
Kod okunurluğu önemli bir noktadır. Bu nedenle, Promise zincirleme ve Promise.all gibi özellikler kullanarak kodlarımızı daha düzenli hale getirebiliriz. Promise.all, birden fazla Promise nesnesini tek bir Promise nesnesinde birleştirir ve tüm işlemler tamamlandığında bir sonuç döndürür. Promise.race ise birden fazla işlem arasında en kısa sürede tamamlanan işlemi geri döndürür.
Async/Await'in Promise'lere göre avantajları arasında okunaklılık ve anlaşılabilirlik bulunur. Async fonksiyonlarının geriye döndürdüğü değer her zaman Promise nesnesidir. Await operatörü, Promise nesnelerini kullanarak birçok işlemi sıraya sokar ve daha düzenli bir kod yapısı oluşturulmasına olanak sağlar.
Sonuç olarak, event-driven sistemlerin tasarımı sırasında Promise ve Async/Await kullanarak kod okunurluğunu ve performansı artırabiliriz. Kodlarımızı daha düzenli hale getirmek için Promise zincirleme, Promise.all ve Promise.race gibi özellikler kullanarak daha fazla kontrol sağlayabiliriz. Event-driven sistemlerin tasarımı, kullanıcılardan aldığımız geri bildirimlere göre şekillenebilir.