Node.js olay döngüsü onayı tam olarak nedir?


84

Node.js mimarisinin iç bileşenlerine daha fazla giriyorum ve çok sık gördüğüm bir terim, "olay döngüsünün bir sonraki tıklaması" veya nextTick () işlevindeki gibi "kene" .

Görmediğim şey, tam olarak bir "tik" nin ne olduğuna dair sağlam bir tanım. Çeşitli makalelere dayanarak (bunun gibi ), kafamda bir kavramı bir araya getirebildim, ancak ne kadar doğru olduğundan emin değilim.

Bir Node.js olay döngüsü onayının kesin ve ayrıntılı bir açıklamasını alabilir miyim?


"döngü" olduğu için, "bir sonraki döngüde" anlamına gelir, bu nedenle bir kene tüm döngüsünü oluşturur, hiçbir olay tetiklenmediğinde ve nodejs herhangi bir tetiklenip tetiklenmediğini kontrol etmek için döngüye girdiğinde sona erer, "nextTick" sonraki anlamına gelir mevcut olandan sonra döngü.
Gntem

Yanıtlar:


156

JavaScript tek iş parçacıklıyken, düğümün tüm G / Ç ve yerel API'lere yapılan çağrıların ya eşzamansız (platforma özgü mekanizmaları kullanarak) ya da ayrı bir iş parçacığında çalıştığını unutmayın. (Bunların tümü libuv aracılığıyla gerçekleştirilir.)

Bu nedenle, bir sokette mevcut veri olduğunda veya yerel bir API işlevi geri geldiğinde, az önce meydana gelen belirli bir olayla ilgilenen JavaScript işlevini çağırmak için senkronize bir yola ihtiyacımız var.

Normal çok iş parçacıklı bir uygulamada karşılaştığınız aynı nedenlerle yerel olayın gerçekleştiği iş parçacığından JS işlevini çağırmak güvenli değildir - yarış koşulları, atomik olmayan bellek erişimi vb.

Yani yaptığımız şey, olayı iş parçacığı açısından güvenli bir şekilde kuyruğa yerleştirmek. Aşırı basitleştirilmiş psuedocode'da şöyle bir şey:

lock (queue) {
    queue.push(event);
}

Ardından, ana JavaScript iş parçacığına geri dönün (ancak şeylerin C tarafında), şöyle bir şey yaparız:

while (true) {
    // this is the beginning of a tick

    lock (queue) {
        var tickEvents = copy(queue); // copy the current queue items into thread-local memory
        queue.empty(); // ..and empty out the shared queue
    }

    for (var i = 0; i < tickEvents.length; i++) {
        InvokeJSFunction(tickEvents[i]);
    }

    // this the end of the tick
}

while (true)(Aslında düğümün kaynak kodunda mevcut olmadığı, bu sadece açıklayıcı olduğu) temsil ettiği olay döngü . İç kısım for, kuyruktaki her olay için JS işlevini çağırır.

Bu bir işarettir: herhangi bir harici olay ile ilişkili sıfır veya daha fazla geri arama işlevinin eşzamanlı çağrılması. Kuyruk boşaltıldıktan ve son işlev geri döndüğünde, tik biter. Başa geri dönüyoruz (bir sonraki tik) ve JavaScript'imiz çalışırken diğer iş parçacıklarından kuyruğa eklenen olayları kontrol ediyoruz .

Sıraya ne ekleyebilir?

  • process.nextTick
  • setTimeout/setInterval
  • I / O (gelen malzeme fs, netve benzeri)
  • cryptokripto akışları, pbkdf2 ve PRNG gibi işlemci yoğun işlevleri (aslında bunlar ...
  • eşzamanlı C / C ++ kitaplık çağrılarının eşzamansız görünmesini sağlamak için libuv iş kuyruğunu kullanan herhangi bir yerel modül

2
Evet bunu başardın. Kuyruğun kopyalanması ve kopyadaki tüm olayların üzerinden geçilmesi, özellikle merak ettiğim şeydi. Şimdi çok mantıklı geliyor. Teşekkürler.
d512

Bu ünlü "Eşzamansız Yineleme kalıbı" algo mu?
Stef

1
@sanjeev, "normal iş" ile ne demek istiyorsun? Devam eden bir JavaScript uygulamasının yaptığı tek şey süreç olaylarıdır.
josh3736

2
Eklemek isterim ki 0.10.x setImmediatede bir işlevi sıraya koyacaktır.
DanielKhan

1
Kene, olay döngü aşaması anlamına mı geliyor?
faressoft

10

JavaScript'e yeni başlayanlar için daha basit bir cevap:

Anlaşılması gereken ilk şey, JavaScript'in "tek iş parçacıklı bir ortam" olduğudur. Bu, JavaScript'in, kod bloklarınızı tek bir iş parçacığı üzerindeki "olay döngüsünden" birer birer yürütme davranışını ifade eder. Aşağıda Kyle Simpson'ın ydkJS kitabından alınan olay döngüsünün temel bir uygulaması ve ardından bir açıklama var:

// `eventLoop` is an array that acts as a queue (first-in, first-out)
var eventLoop = [ ];
var event;

// keep going "forever"
while (true) {
    // perform a "tick"
    if (eventLoop.length > 0) {
        // get the next event in the queue
        event = eventLoop.shift();

        // now, execute the next event
        try {
            event();
        }
        catch (err) {
            reportError(err);
        }
    }
}

İlk while döngüsü olay döngüsünü simüle eder. Bir tik, bir olayın "olay döngü kuyruğundan" çıkarılması ve söz konusu olayın yürütülmesidir.

Bir olayın sırasının kaldırılması ve yürütülmesinde ne olduğu hakkında daha ayrıntılı bir açıklama için lütfen 'Josh3796'nın yanıtına bakın.

Ayrıca, JavaScript'i derinlemesine anlamak isteyenler için Kyle Simpson'ın kitabını okumanızı tavsiye ederim. Tamamen ücretsiz ve açık kaynaklıdır ve şu bağlantıda bulunabilir: https://github.com/getify/You-Dont-Know-JS

Başvurduğum belirli bölüm burada bulunabilir: https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/sync-async/ch1.md


1

Event Loop tick'in çok basit ve kısa yolu:

Bir kuyruktaki istek kümesi işlendiğinde, görevin tamamlanmasını temsil eden onay işaretinin başlatıldığı düğüm dahili mekanizması tarafından kullanılır.


Cevabınız için biraz kaynak sağlayabilir misiniz lütfen?
Kick Buttowski
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.