- Konu sahibi
- #1
JavaScript’te
Bir
Bir async fonksiyon normal bir değer döndürse bile dışarıya verilen sonuç Promise olarak gelir. Sonucu await veya .then() ile alın.
Aşağıdaki örnek, sunucudan veri gelmesini taklit eder. Tarayıcı konsoluna veya Node.js dosyasına doğrudan yapıştırılabilir:
Beklenen çıktı sırasıyla şudur:
İlk
Birden fazla asenkron işlemin birbirinin sonucuna ihtiyacı varsa işlemleri sırayla
İşlemler birbirinden bağımsızsa gereksiz yere art arda
Karar verirken temel ayrım şöyledir:
Zamanlayıcı örneği gerçek ağ isteği yapmaz. Gerçek uygulamada veri alma, ayrıştırma ve iş kuralı hatalarını ayrı değerlendirin. Fetch kullanıldığında HTTP 404/500 her zaman Promise reddi üretmez; response.ok gibi durum bilgisini ayrıca kontrol edin.
Async kelimesi uzun senkron hesaplamayı başka iş parçacığına taşımaz. İlk await öncesinde veya sonrasında ağır döngü çalıştırmak ana iş parçacığını yine meşgul edebilir. Beklemek ile CPU işini arka plana taşımak ayrı konulardır.
Hayır. Ortak Promise reddedilebilir; başlamış işler otomatik iptal edilmez. Gerçek iptal için ilgili API'nin desteklediği mekanizma gerekir. Bütün başarı/hata sonuçlarını toplamak için Promise.allSettled ayrıca değerlendirilebilir.
Hayır. Değer alınabilir fakat await sonrasındaki devam yine asenkron zamanlanır. Aynı çağrı yığını içinde sıradan değişken atamasıyla aynı akışı varsaymayın.
Şart değildir. Örnekte catch yeniden throw etmezse fonksiyon undefined ile başarılı tamamlanabilir. Çağıranın başarısızlığı işlemesi gerekiyorsa yeniden fırlatın veya açık bir sonuç nesnesi döndürün; sözleşmeyi tutarlı belirleyin.
async ve await, Promise tabanlı asenkron işlemleri daha okunabilir yazmayı sağlayan iki anahtar kelimedir. async bir fonksiyonu her zaman Promise döndüren hâle getirir; await ise bu Promise’in sonucunu bekler ve sonucu doğrudan bir değişkene atamanıza izin verir. Bekleme, JavaScript’in tamamını durdurmaz; yalnızca ilgili async fonksiyonun devamını erteler.Nasıl çalışır?
Bir
async fonksiyon içindeki await ifadesi, Promise sonuçlanana kadar fonksiyonun sonraki satırlarını bekletir. Promise başarılı olursa sonuç elde edilir; reddedilirse hata oluşur ve bu hata try...catch ile yakalanabilir.Bir async fonksiyon normal bir değer döndürse bile dışarıya verilen sonuç Promise olarak gelir. Sonucu await veya .then() ile alın.
Çalıştırılabilir en küçük örnek
Aşağıdaki örnek, sunucudan veri gelmesini taklit eder. Tarayıcı konsoluna veya Node.js dosyasına doğrudan yapıştırılabilir:
JavaScript:
function veriGetir() {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ mesaj: "Veri başarıyla alındı" });
}, 500);
});
}
async function uygulamayiCalistir() {
try {
console.log("Veri bekleniyor...");
const sonuc = await veriGetir();
console.log(sonuc.mesaj);
return sonuc;
} catch (hata) {
console.error("İşlem başarısız:", hata);
}
}
uygulamayiCalistir();
Beklenen çıktı sırasıyla şudur:
Kod:
Veri bekleniyor...
Veri başarıyla alındı
İlk
console.log hemen çalışır. veriGetir() tarafından döndürülen Promise tamamlanınca await sonucu sonuc değişkenine aktarır. Promise reddedilirse işlem catch bloğuna gider.Hangi durumda nasıl kullanılmalı?
Birden fazla asenkron işlemin birbirinin sonucuna ihtiyacı varsa işlemleri sırayla
await edin. Örneğin önce kullanıcıyı, sonra o kullanıcıya ait siparişleri almak gerekir.İşlemler birbirinden bağımsızsa gereksiz yere art arda
await kullanmayın. Promise’leri önce başlatıp birlikte beklemek daha uygundur:
JavaScript:
async function verileriGetir() {
const kullanicilarPromise = veriGetir();
const ayarlarPromise = veriGetir();
const [kullanicilar, ayarlar] = await Promise.all([
kullanicilarPromise,
ayarlarPromise
]);
return { kullanicilar, ayarlar };
}
Karar verirken temel ayrım şöyledir:
| Durum | Tercih | Neden |
|---|---|---|
| İkinci işlem birincinin sonucunu kullanıyor | Ardışık await | Bağımlılık vardır |
| İşlemler birbirinden bağımsız | Promise.all | Birlikte başlatılabilirler |
| Hata özel olarak ele alınacak | try...catch | Başarısız durum kontrol edilir |
Sık yapılan hatalar
awaitifadesini normal bir fonksiyonda kullanmak:awaitgenellikleasyncfonksiyon içinde kullanılmalıdır. Modül dosyalarında üst seviyede kullanım ayrıca mümkün olabilir.asyncfonksiyonun sonucunu normal değer sanmak:const sonuc = fonksiyon();ifadesi çoğunlukla gerçek veriyi değil, Promise’i alır. Gerekirseconst sonuc = await fonksiyon();yazın.- Bağımsız işlemleri gereksiz yere sıraya koymak: Her işlemden sonra beklemek toplam süreyi uzatabilir. Bağımsız işlemlerde
Promise.alldeğerlendirin. - Hata kontrolü yapmamak: Ağ isteği, dosya okuma veya veritabanı işlemi başarısız olabilir. Kritik işlemleri
try...catchile çevreleyin. forEachcallback'ini async yapmak: forEach callback Promise sonuçlarını beklemez. Normal callback içinde await yazmak ise sözdizimi hatasıdır. Sıralı işlem içinfor...of, paralel işlem içinmapvePromise.allkullanın.
Hata sözleşmesini belirleme
Zamanlayıcı örneği gerçek ağ isteği yapmaz. Gerçek uygulamada veri alma, ayrıştırma ve iş kuralı hatalarını ayrı değerlendirin. Fetch kullanıldığında HTTP 404/500 her zaman Promise reddi üretmez; response.ok gibi durum bilgisini ayrıca kontrol edin.
Async kelimesi uzun senkron hesaplamayı başka iş parçacığına taşımaz. İlk await öncesinde veya sonrasında ağır döngü çalıştırmak ana iş parçacığını yine meşgul edebilir. Beklemek ile CPU işini arka plana taşımak ayrı konulardır.
Sık sorulan sorular
Promise.all hata verince başlayan diğer işler iptal edilir mi?
Hayır. Ortak Promise reddedilebilir; başlamış işler otomatik iptal edilmez. Gerçek iptal için ilgili API'nin desteklediği mekanizma gerekir. Bütün başarı/hata sonuçlarını toplamak için Promise.allSettled ayrıca değerlendirilebilir.
Promise olmayan değerde await senkron atama gibi mi davranır?
Hayır. Değer alınabilir fakat await sonrasındaki devam yine asenkron zamanlanır. Aynı çağrı yığını içinde sıradan değişken atamasıyla aynı akışı varsaymayın.
Catch içinde yalnız hata yazdırırsam çağıran kod hatayı anlar mı?
Şart değildir. Örnekte catch yeniden throw etmezse fonksiyon undefined ile başarılı tamamlanabilir. Çağıranın başarısızlığı işlemesi gerekiyorsa yeniden fırlatın veya açık bir sonuç nesnesi döndürün; sözleşmeyi tutarlı belirleyin.