JAVASCRIPT’IN TARIHÇESI

Promise -3 (Event Loop)

Onur Dayıbaşı
4 min readDec 13, 2019

--

Browser JS Nasıl İşletir? Stack, Heap, EventLoop, WebAPIs, CallbackQueue, RenderQueue Nasıl işler?

Bu yazıyı daha önceden yazmış olduğum Javascript’in Tarihçesi yazısının bir devamı olarak yazıyorum. Bir çok kavramı tek bir yazıda ele almanın yaratacağı karmaşıklıktan kaçmak için bu yönteme başvurdum. Bu yazılardaki amacım önceden Javascript’in varolan hangi özelliklerinin yetmediğini ve bu geliştirme(ES6) ile neyi hedeflediklerini anlatacağım.

Kısa bir dipnot olarak şunuda belirteyim ki, aslında bu konu teknik olarak İşletim Sistemi, Process, Thread, Concurrency, Non Blocking I/O, Async, Concurrency ve Paralellik ve Fonksiyonel programlama gibi bir çok konuyu dokunuyor. Derinlemesine teknik konularıda okumak için bir önceki yazımı Promise-1(Non-Blocking I/O)

Async mevcut yöntemlerle nasıl kullandığımızı Promise-2(Callback , Async, EventEmitter) yazımda anlattım.

Özetle hangi konuları anlatacağım?

  • Tarayıcılar JS Nasıl İşletilir ?
  • Bellek Kullanımı (Stack vs Heap Nedir ?)
  • Stack Nasıl Çalışır?
  • Asenkron Nasıl Çalışır? (WebAPIs, EventLoop ve TaskQueue)

Özetle hangi konuları anlatMAyacağım?

  • Henüz Promise kavramını anlatmadığım için EventLoop içerisindeki MicroTask/Job Queue yapısının nasıl çalıştığını.
  • Generator EventLoop’da nasıl işletildiğini
  • Browser için konuşacağım için NodeJS EventLoop’ta yer alan Internal C++ thread-pool kavramından bahsetmeyeceğim.
  • ExecutionContext nasıl çalıştığını, Closure ve Scope kavramlarını daha ileride anlatacağım.

1. Tarayıcılar JS Nasıl İşletilir ?

Aslında bu konuyu daha detaylı ele almak isteyenler daha önceden yazmış olduğum Tarayıcılar Nasıl Çalışır yazımı okuyabilirler. Burda anlatacağım ise JS kodunun nasıl ele alınıp işletildiği konusudur.

  • Yazdığımız kod işletilecektir.
  • Senkron kod parçacıklarının işletilmesi. (Sadece Belleği ve İşlemciyi Kullanan)
  • Asenkron DOM Eventlerinin Dinlenmesi(onLoad, onClick, onScroll vb…)
  • AJAX request/response yapılaması (PUT, POST, GET, DELETE …)
  • setTimeout işletilmesi
  • Bu kodların işletilmesinden sorumlu kod EventLoop
  • Boş kalan vakitlerdede Rendering işlerimleri gerçekleştirilir.

EventLoop Single-Thread içerisinde bu işlemleri gerçekleştirir. Aslında burdaki mekanizma Oyun Geliştirmenin Temelleri yazımda anlattığım sonsuz döngü içerisinde Input Listening, Rendering, AI, SoundPlaying, Physics sürekli çağrılmasından çok da farklı değildir.

Sonuçta oyundaki işlemler sizin çok zamanınızı almaya başladığında FPS(Frame Per Seconds) düşeceğinden oyuncunun girdilerine istenen hızda cevap veremez veya ekrandaki animasyonları istenen hızda çizemez. Oyunlarda bu işi ek donanımlarla çözeriz. Yükün sadece CPU üzerinde olmaması için Rendering işlemleri, Fizik işlemleri vb kısımları CPU’dan alıp GPU veya CUDA üzerine aktarılarak FPS’nin üst seviyelerde olması sağlanır.

Bu problemi Tarayıcıların ilk yıllarında yaşadık mesela. AJAX istekleri yerine ekranın tümünü load ediyordu, Asenkron çalışma yapılarının gelmesi sayesinde UI daha reactive bir şekilde çalışmaya başladı. (Reactive Manifesto)

2. Bellek Kullanımı (Stack vs Heap)

CPU’nun aritmetik işlemleri yapabilmesi için Register (Yazmaçları) kullanır. Fakat bu alanlar tüm kodun çalıştırılması için yetmeyecektir. Bundan dolayı CPU memory(belleği) kullanarak işlemlerini gerçekleştirir. Belleği iki şekilde kullanıyoruz Stack ve Heap.

Stack Belleği için statik bellek ayrımı yapılmıştır. Boyutu sınırlıdır. Veriler Stack veri yapısında tutulur. Yani LIFO(Last In First Out), Stack push/pop methodları ile hızlı bir şekilde erişebilirsiniz.. Kodların çalıştırılması sırasında değişkenler ve kod parçacıklarının tutulduğu kısımdır.

Heap Belleği ise Virtual Memory(Sanal Belleğiniz) yani disk üzerinde swap edebilen belleğiniz büyüklüktedir. C malloc, calloc tahsis ettiğimiz yerler bu alanlardır. Boyutları çok geniştir. Stack belleğe göre erişim daha yavaştır. Bellek blokları arasında boşluklar mevcuttur. İstenilen blok veriye istenildiği zaman erişim sağlanabilir.

Heap vs Stack

3. Call Stack Nasıl Çalışır?

Kodun işletilmesini anlatmak oldukça zor. Referanslar bölümündeki video bu konuyu çok iyi anlatıyor. Ben yinede yazıyla anlatayım dersem. Aşağıdaki kodda sayının karesini print eden bir kod var

  • main() ile JS kodu çalıştırılıyor ve printSquare(4) fonksiyonu çağrılıyor
Call Stack Görselleştirme
  • buda kendi içerisindeki çalıştırılacak fonksiyonları sırası ile stack taşıyor. main → printSquare → square → multiply fonksiyonlarını stack yüklüyor.
Call Stack Görselleştirme -2
  • LIFO (Son giren ilk çıkar mantığı ile son fonksiyona geldi ise artık bunları işleterek stack siler. Özetle kod blokları işletildikçe bu stack dolar ve boşalır.
  • Peki stack alanını aşacak şekilde stack dolarsa özellikle foo =() → foo() gibi recursive kod çağrımlarında sistem stack boyutunu aştığınıza dair uyarı verecektir.
Maximum call stack size exceed

Yukarıda gördüğünüz gibi CallStack yapısı oldukça basit. Bir seferde sadece bir işlem yapılabiliyor. Peki nasıl oluyorda bizim tarayıcılar aynı anda birden fazla işlemi yapabiliyor. İşte burda Asenkron çalışma ihtiyacı doğuyor ve bunun için ekstra mekanizmalara ihtiyacımız var.

3. Tarayıcı Asenkron Nasıl Çalışır? (WebAPIs, EventLoop ve TaskQueue)

Biraz önce bahsettiğim Asenkron mekanizması için EventLoop, TaskQueue (CallbackQueue ve WebAPI’s) ihtiyaç duyarız.

  • DOM (Document Object Model)
  • ajax (XMLHttpRequest)
  • setTimeout

vb yapılar Tarayıcıların sağladığı WebAPIs ve bunlar bir takım istekler bulunduğunuzda bunlar ayrı bir thread içerisinde bu işlemlerini gerçekleştirir. Ve bu işlemlerini bitirdiklerinde artık callback çağrılacak fonksiyonu TaskQueue(Callback Queue) içerisine taşır. EventLoop’da CallStack içerisinde işletilecek herhangi bir kod parçası yoksa bunu alıp CallStack taşır ve işletmeye başlar.

WebAPIs saha detaylı incelemek isterseniz Chrome WebAPI kısmını okuyabilirsiniz.

Memory, WebAPIs, EventLoop, TaskQueue

Referanslar

Okumaya Devam Et 😃

Bu yazının devamı veya yazı grubundaki (Tarayıcılar Nasıl Çalışır) diğer yazılara erişmek için bu linke tıklayabilirsiniz.

Bu yazının devamı veya yazı grubundaki diğer yazılara (JS Async Programming) erişmek için bu linke tıklayabilirsiniz.

Bu yazının devamı veya yazı grubundaki diğer yazılara (JS Deep Learning) erişmek için bu linke tıklayabilirsiniz.

--

--