- Katılım
- 7 Nis 2025
- Konular
- 367
- Mesajlar
- 780
- Çözümler
- 1
- Tepkime puanı
- 121
- Puan
- 93
- Konum
- İstanbul
- Web sitesi
- forumagel.com
Hazır Kod Bankası - Konu 26: Asenkron JavaScript (Promises, Async/Await)
Hazır Kod Bankası Serimizin Yirmi Altıncı Konusu: Asenkron JavaScript!
Merhaba arkadaşlar! JavaScript ile web sayfalarını dinamikleştirmeyi ve Fetch API ile API'lere istek göndermeyi öğrendik. Fetch gibi ağ istekleri veya `setTimeout` gibi zamanlayıcılar, kodun hemen sonucunu dönmeyen, zaman alan işlemlerdir. Bu tür işlemler JavaScript'te asenkron (asynchronous) olarak çalışır.
Senkron (Synchronous) Kod: Kod satırları sırayla çalışır ve bir işlem bitmeden (tamamlanana kadar) bir sonraki satıra geçilmez. Eğer zaman alan bir işlem varsa, tüm program o işlem bitene kadar bekler (bloklanır).
Asenkron (Asynchronous) Kod: Kod satırları sırayla çalışmaya başlar, ancak zaman alan bir işlemle karşılaşıldığında, o işlem arka plana atılır ve program beklemeden bir sonraki satırdan çalışmaya devam eder. Zaman alan işlem bittiğinde, sonucu bildirmek için programa geri döner. Bu, özellikle tarayıcıda kullanıcı arayüzünün donup kalmasını engellemek için kritiktir.
JavaScript tek iş parçacıklıdır (single-threaded). Yani aynı anda sadece bir işi doğrudan yapabilir. Asenkron işlemler, zaman alan işleri ana iş parçacığını bloklamadan halletmek için bir mekanizmadır.
Eskiden asenkron kodlar genellikle "callback" fonksiyonları ile yönetilirdi, ancak iç içe callback'ler kodun okunmasını zorlaştırıyordu ("Callback Hell"). Modern JavaScript'te asenkron kodları yönetmek için Promise yapıları ve Promise'lerle çalışmayı çok daha kolay hale getiren Async/Await sözdizimi kullanılır.
Ön Gereksinim: Temel JavaScript bilgisi (Konu 8) ve Fetch API kullanımı (Konu 25) anlaşılmış olmalı.
1. Synchronous vs Asynchronous (Senkron vs Asenkron)[/B]
Basit bir örnekle farkı görelim:
JavaScript:
console.log("1. Senkron İşlem");
// Asenkron işlem - 2 saniye sonra çalışacak
setTimeout(() => { // Arrow function (ok fonksiyonu)
console.log("3. Asenkron İşlem (2 saniye sonra çalıştı)");
}, 2000); // 2000 milisaniye (2 saniye) bekle
console.log("2. Senkron İşlem (Asenkronu beklemeyip hemen çalıştı)");
// Çıktı sırası:
// 1. Senkron İşlem
// 2. Senkron İşlem (Asenkronu beklemeyip hemen çalıştı)
// 3. Asenkron İşlem (2 saniye sonra çalıştı)
2. Promises Nedir?[/B]
Promise (Söz/Vaat), asenkron bir işlemin nihai olarak tamamlanmasını (başarı veya hata ile) temsil eden bir JavaScript objesidir. Bir Promise'in üç durumu olabilir:
- Pending (Beklemede): Asenkron işlem henüz tamamlanmadı.
- Fulfilled (Başarılı): Asenkron işlem başarıyla tamamlandı. Sonuç değeri mevcut.
- Rejected (Reddedildi): Asenkron işlem bir hata ile tamamlandı. Hata sebebi mevcut.
- `.then(onFulfilled, onRejected)`: Promise başarıyla Fulfilled olduğunda çalışacak fonksiyonu (onFulfilled) veya hata ile Rejected olduğunda çalışacak fonksiyonu (onRejected) kaydetmek için kullanılır. Genellikle sadece başarı durumu için ilk parametre kullanılır ve hata için `.catch()` tercih edilir. `.then()` zincirlenebilir, yani bir `.then()` bloğu Promise döndürebilir ve bir sonraki `.then()` bu Promise'in sonucunu bekler.
- `.catch(onRejected)`: Promise Rejected olduğunda çalışacak fonksiyonu kaydetmek için kullanılır. Genellikle bir Promise zincirinin sonuna eklenerek zincirdeki herhangi bir hatayı yakalar.
Fetch API Promise Kullanımı (Konu 25 Tekrarı):
JavaScript:
// API'den veri çekme (GET isteği)
fetch(API_URL + '/products') // fetch bir Promise döner
.then(response => { // İlk .then() Promise resolve olduğunda (yanıt geldiğinde) çalışır
// response objesi geldi, başarılı mı kontrol et
if (!response.ok) {
// Başarısız ise hata fırlat, bu .catch() tarafından yakalanır
throw new Error(`HTTP hata! Status: ${response.status}`);
}
// Yanıt body'sini JSON olarak oku, bu da bir Promise döner
return response.json();
})
.then(data => { // response.json() Promise'ı resolve olduğunda çalışır, parse edilmiş JSON data'yı alırız
console.log('Ürün Listesi:', data);
// Veriyi kullan (HTML güncelle vb.)
})
.catch(error => { // Zincirdeki herhangi bir Promise reject olduğunda (hata olursa) çalışır
console.error('API isteği sırasında bir hata oluştu:', error);
// Hata mesajı göster
});
3. Async / Await Sözdizimi[/B]
Promise'lerin `.then().then().catch()` şeklinde zincirlenmesi bazen karmaşık hale gelebilir. `async` ve `await` anahtar kelimeleri, Promise'lerle çalışmayı senkron koda benzer bir sözdizimiyle yazmayı sağlayarak kodun okunabilirliğini büyük ölçüde artırır.
- `async`: Bir fonksiyonun önüne konulur. Bu fonksiyonun her zaman bir Promise döndüreceğini belirtir ve içinde `await` kullanılmasına izin verir.
- `await`: Sadece bir `async` fonksiyonun içinde kullanılabilir. Önüne konulduğu Promise'in tamamlanmasını bekler. Promise tamamlandığında, `await` ifadenin değeri Promise'in başarı değeri olur. Promise hata verirse, `await` ifadesi hata fırlatır. `await` kullanıldığında, sanki kod o satırda bekliyormuş gibi görünür, ancak aslında `async` fonksiyonun çalışması askıya alınır (ana iş parçacığı bloklanmaz) ve Promise tamamlanınca kalınan yerden devam eder.
Fetch API Kullanımı (Async/Await ile):
JavaScript:
// API'den veri çekme (GET isteği) - async/await ile
async function fetchAndDisplayProductsAsync() { // async fonksiyon tanımla
try { // Hata yönetimi için try...catch kullanılır
console.log("Ürünler çekiliyor...");
// fetch Promise'inin bitmesini bekle
const response = await fetch(API_URL + '/products'); // await ile promise beklenir
// Yanıt başarılı değilse hata fırlat (catch tarafından yakalanır)
if (!response.ok) {
// Hata body'sini de asenkron olarak çekip hata objesine ekleyebiliriz
const errorData = await response.json(); // Hata body'sini bekle
throw new Error(`API hata! Status: ${response.status}, Mesaj: ${errorData.message || response.statusText}`);
}
// Yanıt body'sini JSON olarak oku ve Promise'inin bitmesini bekle
const data = await response.json(); // response.json() Promise'ını bekle
console.log('Ürün Listesi:', data);
// Veriyi kullan (HTML güncelle vb. - Konu 25'teki DOM kodları buraya gelebilir)
} catch (error) { // try bloğunda herhangi bir hata (Promise reject dahil) olursa yakalanır
console.error('API isteği sırasında bir hata oluştu:', error);
// Kullanıcıya hata mesajı göster
} finally {
console.log("Fetch işlemi tamamlandı (başarılı veya hatalı).");
}
}
// Async fonksiyonu çağırma
fetchAndDisplayProductsAsync();
console.log("fetchAndDisplayProductsAsync fonksiyonu çağrıldı..."); // Bu satır fonksiyon içindeki await'i beklemeden çalışır
POST İsteği (Async/Await ile):
JavaScript:
async function addProductAsync(productData, apiKey) {
try {
const response = await fetch(API_URL + '/products', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': apiKey
},
body: JSON.stringify(productData)
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`API Hatası! Status: ${response.status}, Mesaj: ${errorData.message || response.statusText}`);
}
const data = await response.json(); // Başarı mesajını veya eklenen ürünü içeren JSON yanıtı
console.log('Ürün Ekleme Başarılı:', data);
alert('Ürün başarıyla eklendi: ' + data.product.ad); // data.product.ad şeklinde erişim, API yanıtına göre değişir
return data.product; // Eklenen ürünü döndür
} catch (error) {
console.error('Ürün ekleme sırasında bir hata oluştu:', error);
alert('Ürün eklenirken hata oluştu: ' + error.message);
throw error; // Hatayı tekrar fırlat ki çağıran da bilsin
}
}
// Örnek Kullanım (Bir butona tıklanma olayında çağrılabilir)
// const yeniUrunBilgisi = { ad: 'Yeni Kitap', fiyat: 80 };
// const adminKey = 'admin_super_key';
// addProductAsync(yeniUrunBilgisi, adminKey)
// .then(eklenenUrun => { console.log("Ana akışta eklenen ürün:", eklenenUrun); })
// .catch(hata => { console.error("Ana akışta hata yakalandı:", hata); });
Sıra Sizde![/B]
Asenkron JavaScript, Promise'ler ve Async/Await modern JavaScript geliştirmenin temelidir.
- Basit `setTimeout` örnekleri yazarak senkron ve asenkron kod akışını tekrar gözlemleyin.
- Kendi basit Promise'inizi `new Promise((resolve, reject) => { ... });` şeklinde oluşturup `.then()` ve `.catch()` ile tüketmeyi deneyin.
- Konu 25'teki Fetch API ile yaptığınız GET ve POST isteklerini, bu konudaki `async/await` ve `try...catch` sözdizimini kullanarak yeniden yazın.
- Yeniden yazdığınız kodları tarayıcıda çalıştırın ve önceki `.then().catch()` versiyonu ile karşılaştırın, hangisinin daha okunabilir olduğunu düşünün.
- Async fonksiyonların her zaman Promise döndürdüğünü unutmayın. Bir async fonksiyonu çağırdığınızda, sonucunu almak için yine `.then().catch()` kullanmanız gerektiğini veya başka bir async fonksiyonun içinde `await` etmeniz gerektiğini pratik yapın.
Serinin Geleceği?[/B]
Asenkron JavaScript'e (Promises, Async/Await) sağlam bir giriş yaptık. Bu konu, modern web ve Node.js geliştirmede attığınız adımları büyük ölçüde etkileyecektir.
Seriyi buradan sonra nasıl devam ettirelim?
- Async/Await ve Promise'lerde daha ileri konular (Promise.all, Promise.race, Promise zincirleme detayları, asenkron iteratörler)?
- Asenkron hata yönetimi detayları?
- CORS (Cross-Origin Resource Sharing) kavramı ve web güvenliğindeki yeri?
- JavaScript'in çalışma mantığına daha derin bakış (Event Loop)?
- JavaScript Frontend Frameworklerine giriş (React, Vue, Angular)?
- Daha ileri Veri Yapıları ve Algoritma konuları?
- Başka bir programlama diline giriş (C#, C++ gibi)?
- Veya başka önerileriniz mi var?
Umarım bu konu, asenkron kodları daha güvenle yazmanıza yardımcı olur. Görüşmek üzere!
Bu konu, "Hazır Kod Bankası" serisinin yirmi altıncı parçasıdır ve "Yazılım Bilgi ve Yeni Başlayanlar İçin" kategorisi altında paylaşılmıştır.