JavaScript’te Senkron-Asenkron-Thread Kavramları — 2

Fatih Cihan
13 min readFeb 22, 2024

--

Herkese merhaba, bu yazı bir önceki yazının devamı niteliğinde olacağı için bir önceki yazıdaki kavramlar hakkında bilgi sahibi olmanın faydalı olacağını düşünüyorum. İsteyenler bir önceki yazıya buradan ulaşabilir.

Bir önceki yazıda en son callback’ten bahsetmiştik hatta callback’lerin de bir süre sonra bizi callback hell’e doğru götürdüğünü söylemiştik. O zaman biraz da promise kavramı hakkında konuşalım.

Promise Nedir?

Promise, bir asenkron işlemin nihai sonucunu temsil eden bir JavaScript nesnesidir diyebiliriz. Virajı biraz geniş alıp bir önceki yazıda verdiğimiz örnek üzerinden ilerleyecek olursak şöyle düşünebiliriz;

Yukarıdaki örnekte problemimiz neydi? Listeleme işlemini daha önce yaptığımız için yeni kitap eklemiş olsak bile bunu console’da göremiyorduk. Biz bu problemi, 12. satırdaki listBooks fonksiyonunu 18. satırdaki addNewBook fonksiyonunun altında çağırırsak çözebiliyorduk. Ancak biz böyle her ekleme işleminden sonra listeleme fonksiyonunu manuel olarak çağırmak istemeyiz tabii ki. Peki biz bu sorunu callback ile nasıl ele almıştık onu görelim.

Yukarıdaki örneği incelediğimizde 12. ve 17. satırlara bakacak olursak listBooks fonksiyonunu addNewBook fonksiyonuna callback olarak geçtik. Burada callback bizim için ne anlam ifade ediyordu? Bir işlem tamamlandıktan sonra çağırdığımız fonksiyon. Yani yeni bir kitap ekleme işlemi yaptıktan sonra callback fonksiyonunun çalışmasını istiyoruz. Bizim örneğimizde callback fonksiyonu nedir? Tabii ki listBooks fonksiyonudur. Özetle her kitap eklediğimizde otomatik olarak listeleme işlemini de yapıyoruz ve böylece verinin tamamını elde ediyoruz. Şimdi yukarıdaki örneği direkt promise üzerinden yapmadan önce promise nesnesini biraz daha yakından inceleyelim.

Promise tanımını hatırlayacak olursak ne demiştik? Promise, bir asenkron işlemin nihai sonucunu temsil eden bir JavaScript nesnesidir. Yani promise yapısında biz bunun cevabını döneceğiz ya da dönemeyeceğiz ancak biz sana yer tutucu olarak bir promise veriyoruz, sen bu verdiğim sözü al şimdi daha sonra bu sözü yerine getirip getirmememe göre bir cevap dönersin diyoruz. Tabii tanım olarak bunlar bir anlam ifade etmiyor olabilir bu bahsettiklerimizi bir de kod ortamında görürsek daha faydalı olacaktır.

Yukarıdaki örneğe baktığımızda promise1 isminde bir değişken oluşturup new keywordüyle bir promise oluşturuyoruz. Neden new? Çünkü promise için bir nesne demiştik. Bu promise’e parametre olarak bir fonksiyon yazıyoruz. Bu fonksiyona “executor function” diyoruz. Bu executor fonksiyon da iki parametre alıyor. Bu parametreler resolve (başarılı) ve reject (başarısız), ayrıca bu resolve ve reject’in kendileri de ayrı bir fonksiyondur. Şimdi console ekranına baktığımızda promise’in iki tane internal özelliği olduğunu görüyoruz. Bunlardan bir tanesi promise state diğeri ise promise result. Bunları şu şekilde düşünebiliriz, biz bir rest api’a istek attık ve verileri alacağız ancak şu an herhangi bir sonucumuz yok bu yüzden promise state, pending durumunda yani verileri bekliyoruz hâlâ. Promise result’a bakacak olursak o da undefined hâlâ, biz verileri almaya çalışıyoruz ancak daha başarıp başaramadığımız belli değil. Şimdi bir de promise’in resolve durumunu inceleyelim.

Yukarıdaki örneği incelediğimizde resolve ile verileri başarılı bir şekilde aldığımızı düşünebiliriz. İlla veri alıyoruz gibi düşünmek zorunda değiliz bu arada herhangi bir olayın başarılı olması durumunu düşünmemiz yeterlidir ancak burada örneği simüle etmeye çalışıyoruz kafamızda daha iyi canlanması için. Sonuç olarak bir işlemi başarılı şekilde yaptık ve promise’ten bize resolve dönüşü geldi. Console ekranına baktığımızda promise state’in fulfilled (resolved) olduğunu görüyoruz. Tamam biz verileri başarılı bir şekilde aldık ancak promise result’ta hâlâ undefined yazıyor. Neden? Çünkü biz resolve fonksiyonunda bir şey tanımlamıyoruz ki, işlem başarıldı ancak geri döndüğümüz bir şey yok.

Şimdi yukarıdaki örneğe incelersek resolve fonksiyonuna Data şeklinde string bir değer veriyoruz. Şimdi tekrar console ekranına baktığımızda promise result’ın bu sefer Data şeklinde verinin alındığını görüyoruz. Şimdi bir de başarısız (reject) duruma bakalım o halde.

Bu sefer başarısız durumda çalıştıracağımız fonksiyon reject. Console ekranına baktığımızda promise state’in rejected olarak değiştiğini hatta en aşağıda kırmızı bir şekilde hatayı da console’da görüyoruz.

Özetlemek gerekirse promise’in 3 state’i var.
1)Pending -> İsteği gönderdik ancak elimizde hâlâ sonuca dair bir şey yok. Ayrıca promise result undefined. Yani biz promise oluşturduğumuzda o promise’in döneceği değeri ilk durumda bilmiyoruz.
2)Fulfilled -> İsteği gönderdik ve başarılı bir şekilde sonuçlanmış ise
3)Rejected -> İsteği gönderdik ve başarısız bir şekilde sonuçlanmış ise

Peki biz birden fazla sonuç almak istersek nasıl bir durumla karşı karşıya kalırız bir de bu duruma bakalım.

Yukarıdaki örneğe baktığımızda promise fulfilled ve veri olarak da “Data” döndü. Çünkü pending’den ilk resolve’a dönüştüğü için ilk fonksiyonu çalıştırdı biz ilk olarak reject’i çalıştırsaydık direkt console ekranında onu görecektik. Yani bir promise’in state’ini bir kere belirlediysek başarılı veya başarısız o state o promise içinde tekrar değiştirilemez. Bu durum da gayet normal çünkü promise mantığı da tam olarak bu görevi üstleniyordu. Bir işlem ya başarılıdır ya da başarısızdır.

Promise nesnesini inceledikten sonra şimdi de promise nesnesinin içindeki bir değere nasıl ulaşacağımıza bakalım. Diğer objelerdeki gibi dot notation vs ile içindeki değere direkt ulaşamayız. Bunun yerine başarılı durumlar için then yapısını kullanırız. Bir örnek üzerinde görelim o halde.

Dikkat ederseniz yukarıdaki promise bize resolve yani başarılı olarak döndü. Sonucu daha iyi görebilmek adına geriye array döndürmek istedim. Şimdi 5. satıra baktığımızda then metodu içinde bir fonksiyon çalıştıracağız ve bu fonksiyon parametre olarak value alıyor. Bu durumda value, resolve’un içinde gönderdiğimiz değer yani array. Daha sonra bu value’yu ekrana yazdırıyoruz. Bu şekilde veriyi yakalamış olduk tabii ama genel gösterim daha çok şu şekildedir;

Yukarıdaki örneklerde başarılıysa then üzerinden ulaştık şimdi de başarısız (rejected) duruma bakalım.

Yukarıdaki örneğe baktığımızda direkt hatayı yazdırıyor dikkat ederseniz. Bir önceki örnekteki gibi status rejected vs. falan yazdırmıyor. Neden? Çünkü biz then üzerinden ulaşmaya çalışıyoruz, bizim buradaki hataya ulaşmamız için then yerine catch fonksiyonu kullanmamız lazım. (then ile de yakalayabiliriz ancak şimdilik bu durumu göz ardı edelim)

Yukarıdaki örneğe incelediğimizde bir önceki örnekten farkı, 5. satırda artık then yerine catch kullanarak hatayı yakalamayı başardık. Artık bir önceki örnekteki gibi “Uncaught (in promise)” hatası almıyoruz. Direkt console ekranında “ERROR” yazıyor. Ayrıca “value” yerine “reason” kullandık, sanki hatanın sebebini yazdırıyormuş gibi düşünebiliriz. Yani genel kullanım bu şekilde diyebiliriz.

Şimdi then ve catch üzerine biraz daha yoğunlaşalım. Yukarıdaki örneklerdeki gibi biz her zaman resolve’in içindeki değeri yakalamak zorunda değiliz, farklı farklı işlemler de yaptırmak isteyebiliriz. Bizim şu an odaklanmamız gereken yer promise’in sonucundan ilerliyor olmamız. Mesela bi promise oluşturduk çözümlendi veya bir promise oluşturduk reject yedi gibi. Şimdi bir örnek yaparak promise nesnesini biraz daha inceleyelim.

Yukarıdaki örneğe bakacak olursak dikkat ettiyseniz value, undefined durumunda. Çünkü biz resolve’dan direkt olarak değer dönmüyoruz. Biz bu durumda 5. satırdaki then fonkisyonu içinde farklı bir işlem yaptırabiliriz.

Yukarıdaki örneğe bakacak olursak promise bize başarılı bir şekilde döndü, biz de then metodu ile bir şeyler yaptırdık, bir şeyler yaptırdıktan kastımız nedir? Bir fonksiyon çalıştırdık (5. satırdaki arrow fonksiyon) ve ekrana “Veriler alındı” yazdırdık. İşte bu fonksiyon da bir callback fonksiyondur. Yani işlem tamamlandığı zaman; başarılı işlemler then metodu sayesinde, başarısız durumlarda da catch metodu sayesinde direkt yazdırılır. Özetle şunu söyeyebiliriz; then, callback’i resolution durumunda promise’e attach ediyor. Şimdi bir örnekle catch durumunu inceleyelim.

Yukarıdaki örneği incelediğimizde 2. satırda artık promise, resolve değil reject durumunda ve 5. satırda da artık hatayı then ile değil catch ile yakalıyoruz. Yani reject durumunda 5. satırdaki arrow fonksiyonu o promise’e attach et diyoruz. Özetle reject durumunda direkt callback (arrow) fonksiyonu çalıştır diyoruz. Peki biz bunu genel kullanım olarak daha anlaşılır nasıl yazabiliriz bir de ona bakalım.

Yukarıdaki örnekte gördüğümüz gibi then’i ayrı catch’i ayrı yazmaktansa arka arkaya chaining şeklinde de yazabiliriz, dot then tabanlı promise’lerde genel kullanım bu şekildedir. Son olarak ECMAScript 2018 ile beraber gelen finally durumuna bakalım. Finally metodunu, her durumda bize bir sonucun dönülmesini istediğimiz zaman kullanırız. Yani resolve da olsa reject de olsa finally metodu hep çalışacaktır.

Yukarıdaki örneği inceleyecek olursak 13. satırda finally metodunu ekledik ve bu metot resolve ve reject’ten bağımsız olarak çalışacak demiştik. 2. satırda promise resolve olduğu için başarılı bir şekilde console’da “Veriler alindi” yazısından sonra “Hello world” çıktısını yazdırdı. Bu senaryonun aynısı reject durumu için de geçerli olacağından dolayı başarısız durumla ilgili tekrar bir örnek vermiyorum.

Biz buraya kadar then’i genel olarak başarılı durumları yakalıyor demiştik. Aslında hem öyle hem öyle değil. Biz then ile resolve durumuna ek olarak reject durumlarını da yakalayabiliyoruz, şimdi bunu bir örnek ile görelim.

Yukarıdaki örneği inceleyecek olursak 3. satırda promise’i reject olarak verdik, 7. satıra baktığımızda arrow fonksiyon ile bir callback çalıştırmasını istiyoruz, 9. satırda virgül koyarak ikinci bir callback çalıştırmasını istiyoruz. Çünkü then metodu optional olarak iki parametre alır. İlk parametre başarılı olduğunda yani resolved, ikinci parametre ise başarısız olduğunda yani rejected durumunda çalışacak olan callbackler. Yukarıda rejected durumu olduğu için ikinci callback’te bu hatayı yakalayıp ekrana “Veriler alinmadi” şeklinde yazdırdık. Yani özetle biz, then ile reject durumunu da yakalayabiliyoruz. Ama genel olarak then ve catch kullanılır.

Şimdi de callback kullanarak yaptığımız kitap örneğini bir de promise üzerinden yaparak konuyu daha iyi anlamaya çalışalım.

Şimdi yukarıdaki örneğe bakacak olursak 1. satırda books array’i ve 6. satırdaki listBooks fonksiyonları bir önceki callback kullanarak yaptığımız örnek ile aynı kodlar. Burada odaklanmamız gereken yer 12. satırdaki addNewBook fonksiyonu, dışarıdan newBook isminde bir parametre alıyor. Ancak bu kez callback fonksiyonu dönmeyeceğiz, onun yerine promise döneceğiz. 13. satırda promise’imizi oluşturduk, parametre olarak executor fonksiyonumuz da resolve ve reject isminde iki parametre (bunlar da fonksiyon) alıyor. Burada bizim yapmak istediğimiz şey books array’ine bir kitap daha eklemek ve bu yüzden 14. satırda push metodu yardımıyla parametre olarak gelen kitabı ekliyoruz. Başarılı olduğunu varsayalım ve bu durumda resolve kitapların kendisini dönecek. Son olarak 17. satırda da bu promise’i return ediyoruz. 20. satıra geldiğimizde artık promise tabanlı fonksiyonu çalıştırmamız gerekecek. Zygmunt Bauman’dan Yaşam Sanatı isimli kitap objesini parametre olarak gönderiyoruz. 21. satırda then’e register edilmiş callback’i çalıştırmasını istiyoruz. Yani ekrana “Yeni liste” dedikten sonra console’da kitapların listelenmesini istiyoruz dolayısıyla 23. satırda listBooks fonksiyonunu çağırıyoruz. Daha sonra bir hata durumunda catch’e register edilmiş callback’i çalıştırmasını isteyeceğimiz için catch’in içindeki parametreye reason yazıyoruz, sonrasında bu reason’ı yani hatanın sebebini ekrana yazdırmak istiyoruz. Burada önemli olan, 21. ve 25. satırdaki callback’lerin hangi koşullarda çalıştırılacağına karar vermek.

Şimdi promise üzerinden bir örnek daha yapalım. Ancak bu sefer geciken veri gibi bir durumu değil de yanlış veri girmeyle ilgili bir örnek yapalım.

Şimdi yukarıdaki örneği incelediğimizde addTwoNumbers fonksiyonu num1 ve num2 değişkenlerini alıyor, 2. satırda bir promise oluşturuyoruz. Promise, parametre olarak resolve ve reject metotlarını alıp arrow fonksiyon olarak yazdırıyoruz. 3. satırda sayıların toplamını alıyoruz.
4. satırda ise typeof ile girilen parametrelerin tiplerini kontrol ediyoruz, yani number olmasını istiyoruz. Eğer ikisi de number değilse hata yazdıracağız. Daha sonra 5. satırda reject case’i için hata mesajını yazdırıyoruz, 6. satırda resolve durumunda ise sum değişkeninin dönmesini istiyoruz. Son olarak 8. satırda promise’i return ediyoruz.
11. satıra geldiğimizde addTwoNumbers fonksiyonuna 7 ve 3 parametrelerini verip invoke ediyoruz, sonrasında then ile gelen sum değerini yakalayıp ekrana yazdırıyoruz. Eğer parametrelerden birini number dışında bir değer verirsek catch ile hatayı yakalayıp ekrana yazdırıyoruz. Biz yukarıda parametre olarak iki rakam verdiğimiz için fonksiyonumuz 10 değerini ekrana yazdırdı, aksi halde iki parametreden herhangi birini number veri tipi dışında girdiğimizde ise catch metodu ile hatayı yakalayıp ekranda gösterebiliriz. Bu örneği yapma sebebimiz, promise’i her zaman asenkron fonksiyonlarda veya gelen veri gecikmelerinde kullanmak zorunda değiliz, bu tarz hata yakalama işlemlerinde de kullanabiliriz. Burada önemli olan, resolve ve reject durumlarında ilgili callback fonksiyonu çalıştırmak.

Buraya kadar promise’in asenkron operasyonları yönetmek için oldukça güçlü bir yapı olduğunu gördük. Ancak callback’lerde olduğu gibi promise’ler de bazı durumlarda kodun karmaşıklaşmasına ve anlaşılabilirliğin azalmasına neden olabilir. Bu sebepten dolayı ES8 ile beraber gelen async/await yapısı, JavaScript’teki asenkron programlamayı daha okunabilir ve anlaşabilir hale getirmek için sunulmuş bir syntax’tır. Temelde promise’lerin daha etkili ve temiz bir şekilde kullanılmasını sağlayan bir yapı gibi düşünebiliriz. Yani async/await yapısı, promise zincirlerini ve callback fonksiyonlarını kullanmaktan daha temiz bir kod sunarlar. Bu nedenle modern JavaScript kodundan asenkron işlemleri yönetmek için sıkça tercih edilen bir yöntemdir.

Şimdi gelelim async/await yapısını biraz daha yakından incelemeye; async fonkisyonlar, bir fonksiyonun asenkron olduğunu belirtmek için kullanılır ve bu fonksiyonlar her zaman bir promise nesnesi döndürür. Await’e bakacak olursak, sadece async fonksiyonlar içinde kullanılabilir. Yani asenkron bir işlemin tamamlanmasını beklerken, bu işlemin sonucunu almak ve işlem sonucuna göre bir sonraki adımı belirlemek için kullanılır. Özetle bir fonksiyonu async keywordü ile kullanırsak bize bir promise döner. Await ise promise nesnesi döndüren bir işleme uygulanır ve bu işlem tamamlanana kadar fonksiyonun durmasını sağlar. Şimdi de bu bahsettiklerimizi bir de kod ortamında görelim.

Evet yukarıdaki örnekte de gördüğümüz gibi, async keywordü kullanarak oluşturduğumuz fonksiyon bize bir promise nesnesi döndürdüğünü görüyoruz. Artık promise nesnesini daha önce gördüğümüz gibi then ve catch ile handle edebiliriz. Daha önce callback ile sonrasında promise ile yaptığımız kitap ekleme örneğimizi bu sefer de async/await ile yaparak farkları ve sadeliği daha iyi görelim.

Şimdi yukarıdaki örneğe baktığımızda 12. satırda addNewBook fonksiyonunu async olarak tanımladık. Bu, fonksiyonun asenkron bir işlem gerçekleştirebileceğini ve await keywordü içerebileceğini belirtir. Bu durumda, addNewBook fonksiyonu asenkron bir şekilde çalışır ve promise döndürür. Asenkron çalışır demek ile neyi kastediyoruz peki? Şunu kastediyoruz; addNewBook fonksiyonunun kod bloğunun, programın geri kalanından bağımsız olarak çalışacağı anlamına gelir. Yani addNewBook fonksiyonu çalıştırıldığında, içindeki işlemler diğer kodların beklemesiyle engellenmez. 17. satırdaki main fonksiyonuna baktığımızda o da async olarak tanımlanmıştır. Yani asenkron bir işlem gerçekleştirebileceğini ve await keywordünü içerebileceğini belirtir. Bu main fonksiyonun içinde ise try-catch bloğu kullandık. Bu try-catch bloğunu, await keywordüyle beklenen işlemlerde oluşabilecek hataları yönetmek için kullanırız. Eğer await ile beklediğimiz işlem başarılı olursa try bloğundaki kodlar çalıştırılır. Eğer herhangi bir hata oluşursa catch bloğu çalıştırılır ve hata yakalanır.

Artık konuyu toparlamak ve noktalamak açısından JSONPlaceholder üzerinden son bir örnek yapalım. Öncelikle JSONPlaceholder, JSON verilerini API üzerinden sunan ve biz geliştiricilerin uygulama geliştirme sürecinde kullanabileceği ücretsiz bir JSON hizmetidir. Yani örnek verilerle doldurulmuş bir RESTful API hizmeti sunar ve biz de get, post, put ve delete gibi HTTP istekleriyle CRUD işlemlerini gerçekleştirmemizi sağlar diyebiliriz.

Senaryomuzu şöyle kuralım, post id’si 1 olan post’un yorumlarını getirmek istiyoruz.

https://jsonplaceholder.typicode.com/

Şimdi bizim yukarıdaki senaryoyu uygulamamız için iki tane istek atmamız lazım. Birincisi, post id’si 1 olanın id’sini getir. Daha sonra yakaladığımız id’yi post id’ye parametre olarak geçirip bu post’un yorumlarını getir dememiz lazım. Tabii böyle kuru kuru anlatmaktansa gelin bu bahsettiklerimizi bir de kod ortamında görelim. Bu bahsettiğimiz senaryoyu ilk önce promise üzerinden daha sonra async/await yapısı üzerinden kurgulayacağız. Ee yukarıda zaten kitap örneği üzerinden görmüştük diyebilirsiniz ama RESTful API’a istek atarak yapmanın gerçek hayat projelerini daha iyi anlamamızı sağlayacağını düşünüyorum.

Şimdi yukarıda yaptığımız örneği açıklamaya çalışalım. Biz ilgili butonu clicklediğimizde arrow fonksiyon çalıştı ve fetch API ile post’u 1 olanın post’unu getir diyoruz, tabii bize bir promise döndüğü için bunu then ile yakaladık ve 3. satıra baktığımızda; res parametresi, fetch işleminin yanıtını temsil eden bir değişkendir. (res yerine istediğimiz değişken ismini verebiliriz) Bu yanıt, bir HTTP isteğinin yanıtıdır ve JSON formatında veri içerir bu sebepten res.json() ifadesi ile yanıtı alıp ve bu yanıtı JSON formatına dönüştürüyoruz. Tabii res.json() da bize bir promise döndüğü için 4. satırda tekrar then ile yakalıyoruz. Artık burada post’umuzu yakaladık. 5. satırda da bu post’un id’sini ekrana yazdırdık, zaten bizim için önemli olan post’un id’siydi. Daha sonra 6. satıra gelerek fetch API ile tekrar bir istek atıyoruz bu sefer de yakaladığımız post’un id’sini veriyoruz. Çünkü dinamik olmasını istiyoruz, şu an id’si 1 olan post üzerinden ilerliyoruz tamam ancak ilerleyen zamanlarda id’si 2 olan post’un yorumlarını da görmek isteyebiliriz. Artık fetch API’ın bize promise döndüğünü artık biliyoruz ve bunu 7. satırda then ile yakalıyoruz. Sonrasında gelen response’u JSON’a çeviriyoruz ve bu da bize promise döndüğü için 8. satırda tekrar then ile yakalayıp ilgili yorumları console’da gösteriyoruz. Bu basit örnekten de anlaşılacağı üzere iç içe bir then zinciri oluşmaya başlıyor inceden ve kodun okunulabilirliği iyice azalmaya başlıyor. Şimdi bunun aynısını async/await üzerinden yapalım.

Şimdi yukarıdaki örneği incelediğimizde butona tıkladığımızda bir event listener fonksiyonu içinde bir arrow fonksiyon tanımladık ancak dikkat ederseniz bu fonksiyonu bir önceki örnekten farklı olarak async keywordü ile tanımladık. Bunun nedeni, içinde await keywordünü kullanabilmek için. 2. satıra geldiğimizde fetch API ile sunucuya bir istek attık gayet güzel, ancak bizim kontrolümüz dışımızda sunucuda problemler olabilir. (sunucu çökmüş olabilir, yoğunluk olabilir vs.) Yani sunucudan veriyi alıp bize getirmesi için arada belirli bir süre var ve biz bu süreyi kestiremiyoruz. İşte bu 2. satırın beklemesi gerekiyor. Biz bu bekletme işini await keywordü ile yapıyoruz. Özetle 2. satırda fetch ile bir HTTP isteği yaptık ve bu isteğin sonucunda bize bir response tipinde bir promise nesnesi döndü. Bu response’u, responsePost isminde bir değişkene atadık. 3. satıra baktığımızda await ile tekrar bekleterek responsePost.json() dedikten sonra response içindeki veriyi alıyoruz ve bunu da post değişkenine atıyoruz. Eğer bir yerde promise dönüyorsa bunu await kullanarak sürecin tamamlanmasını bekletmek zorundayız ki asenkron problemi yaşamayalım. Yani ilk önce 2. satır bitsin daha sonra 3. satıra geçsin diyebilmek için await kullanıyoruz. Buraya kadar post’u aldık gayet güzel,
4. satıra baktığımızda tekrar fetch API ile bir istek atıp bu satırı da await ile bekletiyoruz çünkü burası da asenkron çalışıyor. 5. satırda ise yorumları alabilmek için responseCommet.json() diyerek ilgili yorumları alıyoruz tabii await ile bekletiyoruz. Neden await ile bekletiyoruz? Çünkü json metodu da bize bir promise dönüyor ve bu promise’i de bekletmemiz gerekiyor. Son olarak 6. satırda ise ilgili yorumları ekranda başarılı bir şekilde gösteriyoruz. Son olarak yukarıda yaptığımız örneği biraz daha kısaltıp daha okunur hale getirmek istersek şöyle bir yaklaşım sergileyebiliriz.

Evet arkadaşlar, bu yazıda sizlere elimden geldiği kadar sade bir şekilde JavaScript’te senkron, asenkron, promise, async/await konularından bahsetmeye çalıştım. Umarım bu konular hakkında daha iyi bir anlayış kazanmanıza yardımcı olmuştur, iyi çalışmalar.

Referanslar;
1)Arin Yazılım
2)freeCodeCamp — Joy Shah
3)JavaScript MDN
4)Tarık Güney — Event Loop, Async, Single Thread
5)Enes Bayram — Async/Await

--

--