Sanırım bir kez çalıştırıldığında kuyrukta, ancak kuyrukta tam olarak X milisaniyeden sonra devreye gireceğine dair herhangi bir garanti var mı? Yoksa kuyruktaki diğer ağır görevler geciktirir mi?
Sanırım bir kez çalıştırıldığında kuyrukta, ancak kuyrukta tam olarak X milisaniyeden sonra devreye gireceğine dair herhangi bir garanti var mı? Yoksa kuyruktaki diğer ağır görevler geciktirir mi?
Yanıtlar:
SetTimeout'un semantiği, bir web tarayıcısındaki ile kabaca aynıdır: zaman aşımı argümanı, bir garanti değil, çalıştırmadan önce beklenecek minimum ms sayısıdır. Ayrıca, sayı olmayan veya negatif bir sayı olan 0'ı geçmek, minimum sayıda ms beklemesine neden olur. Düğümde bu 1 ms'dir, ancak tarayıcılarda 50 ms'ye kadar çıkabilir.
Bunun nedeni, JavaScript tarafından JavaScript'in önceden belirlenmiş olmamasıdır. Şu örneği düşünün:
setTimeout(function () {
console.log('boo')
}, 100)
var end = Date.now() + 5000
while (Date.now() < end) ;
console.log('imma let you finish but blocking the event loop is the best bug of all TIME')
Buradaki akış:
Eğer durum bu değilse, o zaman bir bit JavaScript diğerini "kesintiye uğratabilir". Böyle bir kodun akıl yürütmesinin son derece zor olmasını önlemek için muteksler ve semaforlar kurmamız gerekir:
var a = 100;
setTimeout(function () {
a = 0;
}, 0);
var b = a; // 100 or 0?
Node'un JavaScript yürütmesinin tek iş parçacıklı olması, diğer eşzamanlılık stillerinin çoğundan çok daha kolay çalışılmasını sağlar. Elbette, değiş tokuş, programın kötü davranan bir bölümünün her şeyi sonsuz bir döngü ile engellemesinin mümkün olmasıdır.
Bu, savaşmanın karmaşıklığından daha iyi bir şeytan mı? Bu bağlıdır.
console.log
mesaj için +1 alırsınız.
Engellememe fikri, döngü yinelemelerinin hızlı olmasıdır. Bu nedenle, her işaret için yineleme yapmak, setTimeout'un makul bir kesinlik dahilinde doğru olacağı kadar kısa bir süre almalıdır (kapalı belki <100 ms kadar).
Teorik olarak haklı olmanıza rağmen. Bir uygulama yazarsam ve onay işaretini engellersem, setTimeout'lar gecikecektir. Öyleyse sorunuzu cevaplamak için, setTimeout'ların zamanında çalışmasını kim temin edebilir? Siz, engelleyici olmayan kod yazarak, neredeyse her türlü makul doğruluk derecesine kadar doğruluk derecesini kontrol edebilirsiniz.
JavaScript kod yürütme açısından "tek iş parçacıklı" olduğu sürece (web çalışanları ve benzerleri hariç), bu her zaman olacaktır. Tek iş parçacıklı yapı çoğu durumda büyük bir basitleştirmedir, ancak engellemeyen deyimin başarılı olmasını gerektirir.
Bu kodu tarayıcınızda veya düğümde deneyin ve doğruluk garantisinin olmadığını göreceksiniz, aksine setTimeout çok geç olacak:
var start = Date.now();
// expecting something close to 500
setTimeout(function(){ console.log(Date.now() - start); }, 500);
// fiddle with the number of iterations depending on how quick your machine is
for(var i=0; i<5000000; ++i){}
Tercüman döngüyü optimize etmedikçe (kromda yapmaz), binler içinde bir şey elde edersiniz. Halkayı çıkarın ve burnunuzda 500 olduğunu göreceksiniz ...
Kodun yürütüldüğünden emin olmanın tek yolu, setTimeout mantığınızı farklı bir işleme yerleştirmektir.
Mantığınızı gerçekleştiren ve bir tür akış (belki tcp) aracılığıyla bu işleme veri ileten yeni bir node.js programı oluşturmak için çocuk süreç modülünü kullanın.
Bu şekilde, ana sürecinizde bazı uzun engelleme kodu çalışıyor olsa bile, çocuk işleminiz zaten kendi kendine başlamış ve yeni bir işlem ve yeni bir iş parçacığına bir setTimeout yerleştirmiştir ve böylece beklediğinizde çalışacaktır.
Daha fazla karmaşıklık, daha fazla iş parçacığının çalıştığı ve ardından işlemlerin olduğu bir donanım düzeyindedir ve bu nedenle bağlam değiştirme, beklenen zamanlamada (çok küçük) gecikmelere neden olur. Bu önemsiz olmalı ve önemliyse, ne yapmaya çalıştığınızı, neden bu kadar doğruluğa ihtiyacınız olduğunu ve bunun yerine işi yapmak için ne tür gerçek zamanlı alternatif donanımların mevcut olduğunu ciddi olarak düşünmeniz gerekir.
Genel olarak, alt süreçleri kullanmak ve birden çok düğüm uygulamasını ayrı işlemler olarak bir yük dengeleyici veya paylaşılan veri depolama (redis gibi) ile birlikte çalıştırmak kodunuzu ölçeklendirmek için önemlidir.
setTimeout
bir tür iş parçacığıdır , belirli bir süre için bir işlemi tutar ve yürütür.
setTimeout(function,time_in_mills);
burada ilk bağımsız değişken bir işlev türü olmalıdır; örnek olarak isminizi 3 saniye sonra yazdırmak istiyorsanız, kodunuz aşağıdaki gibi olmalıdır.
setTimeout(function(){console.log('your name')},3000);
Hatırlanması gereken anahtar nokta, setTimeout
yöntemi kullanarak yapmak istediğiniz her şeyi bir işlevin içinde yapmaktır . Bazı parametreleri ayrıştırarak başka bir yöntemi çağırmak istiyorsanız, kodunuz aşağıdaki gibi görünmelidir:
setTimeout(function(){yourOtherMethod(parameter);},3000);
setTimeout(callback,t)
en az t milisaniye sonra geri aramayı çalıştırmak için kullanılır . Gerçek gecikme, işletim sistemi zamanlayıcı ayrıntı düzeyi ve sistem yükü gibi birçok harici faktöre bağlıdır.
Bu nedenle, ayarlanan süreden biraz sonra çağrılma olasılığı vardır, ancak daha önce asla çağrılmayacaktır.
Bir zamanlayıcı 24,8 günden fazla olamaz.