JavaScript Senkron — Asenkron Karmaşası
Hadi başlayalım,
Herkese merhaba! Javascript öğrenmeye çalışırken en çok zorlandığım konulardan biri olan “Asynchronous” yani asenkron çalışmanın mantığını elimden geldiğince basitleştirip açıklamaya çalışacağım.
Javascript öğrenmeye başlayan herkes kullandığı kaynaklarda şöyle bir tanıma muhakkak denk gelmiştir: “ Javascript single-thread ve eş zamanlı (synchronous) bir yazılım dilidir…”. Bunu öğrenip devam ediyoruz ve sonra öğrenmenin ilerleyen süreçlerinde kullanmaya başladığımız async-await/promises-then gibi ifadeler ile akıllar karışmaya ve bu ilk tanım çoğu insan için anlamsızlaşmaya başlıyor.
Şimdi gelin hep birlikte Javascript’te bu karmaşaya ne sebep oluyor inceleyelim.Single-thread ve synchronous dedik, yani JS her yazdığımız kod bloğunu sırayla okuyor, birini tamamlamadan diğerine geçmiyor. Bunu anlamamız için küçük bir örnek aşağıda;
https://medium.com/media/4aaabad7687f48c03b7ad31877eb0286/hrefBu kodun çıktısını birlikte inceleyelim, tarayıcımızı açtığımızda;
foo() fonskiyonumuz çalıştı konsola 2 satır logladı ve alert verdi. Biz “Tamam” butonuna basmadığımız sürece de sayfada veya konsolda herhangi bir değişiklik olmuyor. Hadi “Tamam” butonuna basalım;
Tamam butonuna tıklamamızla birlikte foo() fonksiyonu tamamlandı ve ondan sonra gelen bar() fonksiyonumuz çalışıp konsola 2 satır logladı. Buradan JS’in aslında single-thread olduğunu net bir şekilde anlayabiliyoruz. Biz “Tamam” butonuna basmadan bar() fonksiyonumuz çalışmadı.
CallStack nedir?
Şimdi işleri biraz daha karmaşık hale getirelim;
https://medium.com/media/9ca32f9d16984f961cd47704be1eaa86/hrefŞimdi öncelikle bu kodun çıktısına bakalım, sonra da gelin birlikte anlamaya çalışalım.
Biz foo() fonksiyonunu invoke ettik ve foo() içindeki ilk satır konsola “Foo” logladı. Hemen ardından ise sıradaki satırda ki bar() fonksiyonu çağrıldı ve bar() fonskiyonunun ilk satırı çalışıp konsola “Bar” yazdırdı. Ve bar() fonksiyonu 2. satırına geçip baz() fonksiyonunu çalıştırdı. Şuan JS runtime’da şöyle bir görüntü var:
Şemada gördüğümüz “stack” alanını aslında bir konser sırası gibi düşünebiliriz. Ama stack mantığında işler biraz ters yürüyor ilk giren son çıkıyor :) Şimdi bizim programımızın tamamlanması için sırasıyla Baz() -> Bar() -> Foo() tamamlanmalı. Baz tamamlanmadan Bar, Bar tamamlanmadan da Foo tamamlanamaz. İşte tam olarak bu yüzden “ Javascript single-thread ve eş zamanlı (synchronous) bir yazılım dilidir…”. Peki o zaman javascript’te Asynchronous nedir? Bu işleyişi nasıl manipüle ediyoruz? Ve senkron olmayan işlemleri yaparken arkaplanda neler dönüyor? Gelin birlikte öğrenelim.
Biz sonucunu almamızın uzun süreceğini bildiğimiz, veya bir sebeple sıraya sokmak istediğimiz işlemleri senkron olarak çalıştırmak isteriz. Örneğin fetch ile bir API’a istek gönderdiğimizde dönüşü beklerken programımızın devam etmesini ve data hazır olduğunda kullandığımız yere onu göndermesini isteriz. Bunu yapmamız için JS’in muhteşem bir sırası daha var CallBack Queue. Eğer biz kod yazarken JS’e yazdığımız fonksiyonun uzun süreceğini belirtebilirsek JS o fonksiyonu önce Web API’ya aktaracak orada işlem tamamlanırken kendisi stack’te bulunan işlerini yapmaya devam edecektir. Web API’da tamamlanan görev ise CallBack Queue’ya aktarılarak Stack’te ki işlemlerin tamamlanıp sıranın kendisine gelmesini bekler.
Son olarak,
Özet olarak son örneğimizi konuşalım ; konsola“ hello world” yazacak bir setTimeOut() fonksiyonu hayal edelim.
https://medium.com/media/2cbd0b6abaf1f369e8b9a66f0b69b023/hrefJS bu fonksiyonun sırası geldiğinde çalıştırıp Web API’ya aktarır ve stackte kalan işlemlerine devam eder. Web API kısmında setTimeout’a karşılık bir 2000ms’lik bir kronometre görevi oluşur. Bu zamanlayıcı görevini tamamlayıp sıfır olduğunda ise JS bunu CallStack’e aktarır. Stackte bulunan görevlerin tamamlanmasının ardından bu görev Stack’e alınarak taşıdığı “Hello World” komutunu konsola yazdırır.
Javascript’in bu özelliğini data çekerken, event yönetirken ve timerlarda kullanmaktayız.
Sonuç olarak Javascript hala “ …single-thread ve eş zamanlı (synchronous) bir yazılım dilidir…”. Ama biz çeşitli araçlarla onu manipüle edip istediğimiz şekilde çalışmasını sağlıyoruz.
Sevgilerimle,
Kodla kalın.