console.log () eşzamansız mı yoksa eşit mi?


93

Şu anda Trevor Burnham'ın Async Javascript yazısını okuyorum . Bu şimdiye kadar harika bir kitap oldu.

Bu snippet ve console.log'un Safari ve Chrome konsolunda 'eşzamansız' olduğundan bahsediyor. Maalesef bunu kopyalayamıyorum. İşte kod:

var obj = {}; 
console.log(obj); 
obj.foo = 'bar';
// my outcome: Object{}; 'bar';
// The book outcome: {foo:bar};

Bu eşzamansız olsaydı, sonucun kitap çıktısı olacağını beklerdim. console.log (), tüm kod çalıştırılana kadar olay kuyruğuna yerleştirilir, ardından çalıştırılır ve bar özelliğine sahip olur.

Eşzamanlı olarak çalışmasına rağmen görünüyor.

Bu kodu yanlış mı çalıştırıyorum? Console.log aslında eşzamansız mı?


@thefourtheye: Hayır, bu yüzden muhtemelen yorumumu silmeliyim.
kurabiye canavarı

1
Bunun Chrome'da olduğunu gördüm. Basit bir nesneyi console.log yaparsanız ve ardından nesnedeki bir şeyi hemen değiştirirseniz, console.log()her zaman önceki değeri göstermez. Bu sizin başınıza gelirse geçici çözüm, yapmaya çalıştığınız şeyi console.log()değişmez olan bir dizeye dönüştürmektir, bu nedenle bu soruna tabi değildir. Dolayısıyla, deneyimlerden console.log(), muhtemelen süreç sınırları boyunca verileri sıralamakla ilgili bazı eşzamansız sorunlar vardır. Bu amaçlanan davranış değildir, ancak console.log()dahili olarak nasıl çalıştığının bazı yan etkileridir (şahsen bunu bir hata olarak değerlendiririm).
jfriend00


1
@bergi Bu dupe'yi bulmam 10 dakikamı aldı (tam adını bilmeme rağmen), muhtemelen çift kapalı olduğu için. Kopyayı değiştiremez miyiz, böylece diğeri de kopya olur ...?
Jonas Wilms

1
@JonasWilms Şimdi bu soruyu yeniden açtım ( tarihe bakın ). Birbirlerinin kopyası olduklarını düşünmüyorum, kullanıyorum Chrome'un JavaScript konsolu dizileri değerlendirme konusunda tembel mi? özellikle bir diziyi içeren problemler için kanonik hedef olarak.
Bergi

Yanıtlar:


114

console.logstandartlaştırılmamıştır, bu nedenle davranış oldukça tanımsızdır ve geliştirici araçlarının yayından sürümüne kolayca değiştirilebilir. Yakında cevabımın yanı sıra kitabınız büyük olasılıkla güncelliğini yitirecek.

console.logKodumuza göre, eşzamansız olup olmaması bir fark yaratmaz, herhangi bir geri arama falan sağlamaz; ve ilettiğiniz değerler her zaman referans alınır ve işlevi çağırdığınız anda hesaplanır.

O zaman ne olacağını gerçekten bilmiyoruz (Tamam, yapabiliriz, çünkü Firebug, Chrome Devtools ve Opera Dragonfly hepsi açık kaynak kodludur). Konsolun kaydedilen değerleri bir yerde saklaması gerekecek ve bunları ekranda gösterecektir. Oluşturma, konsoldaki günlüğe kaydedilen nesnelerle gelecekteki etkileşimler (nesne özelliklerini genişletmek gibi) gibi, kesinlikle eşzamansız olarak gerçekleşecektir (hız sınırı güncellemelerine göre kısılacaktır).

Dolayısıyla konsol, günlüğe kaydettiğiniz değiştirilebilir nesneleri klonlayabilir (seri hale getirebilir) veya bunlara referansları depolayabilir. İlki derin / büyük nesnelerle iyi çalışmıyor. Ayrıca, en azından konsoldaki ilk işleme, muhtemelen nesnenin "mevcut" durumunu, yani oturum açıldığı zamandaki durumu gösterecektir - örneğinizde gördüğünüz Object {}.

Ancak, özelliklerini daha fazla incelemek için nesneyi genişlettiğinizde, konsolun nesnenize ve özelliklerine yalnızca bir başvuru kaydetmesi olasıdır ve bunları şimdi görüntülemek, mevcut (zaten değiştirilmiş) durumlarını gösterecektir. Eğer üzerine tıklarsanız, örneğinizde mülkü +görebilmeniz gerekir bar.

Aşağıda , "düzeltmeyi" açıklamak için hata raporunda yayınlanan bir ekran görüntüsü verilmiştir :

Bu nedenle, bazı değerlere günlüğe kaydedildikten çok sonra başvurulabilir ve bunların değerlendirilmesi oldukça tembeldir ("gerektiğinde"). Bu tutarsızlığın en ünlü örneği, Chrome'un JavaScript konsolu dizileri değerlendirme konusunda tembel mi?

Geçici bir çözüm, örneğin yaparak nesnelerinizin her zaman serileştirilmiş anlık görüntülerini günlüğe kaydettiğinizden emin olmaktır console.log(JSON.stringify(obj)). Bu, dairesel olmayan ve oldukça küçük nesneler için işe yarayacaktır. Ayrıca Safari'de console.log'un varsayılan davranışını nasıl değiştirebilirim? Konusuna bakın. .

Daha iyi çözüm, yürütmenin tamamen durduğu ve her noktada mevcut değerleri inceleyebileceğiniz hata ayıklama için kesme noktaları kullanmaktır. Günlük kaydını yalnızca serileştirilebilir ve değiştirilemez verilerle kullanın.


2
console.log'un eşzamansız olmamasıyla aynı sorunu yaşadım. JSON.stringify benim için sabit kullanarak
russiansummer

2019 itibariyle, console.logChrome'da 8 yaşında olduğu için hala eşzamansız olduğunu söyleyebilir miyiz (bkz. Stackoverflow.com/questions/7389069/… ), değişen tek şey artık Chrome'un referans nesnesinin anlık görüntüsünü aradığınız zaman console.log(günlüğe kaydedilen nesneyi genişletirseniz, daha sonra yaptığınız mutasyon işlemlerinden sonra son özelliklerini ve değerlerini göreceksiniz console.log) veya console.loggerçekten eşzamanlı mı?
tonix

@tonix Evet, cevabımda belirtilen nedenlerden dolayı bu davranışın değiştirilmesi olası değildir. Bu bir hata değil, etkileşimli bir hata ayıklayıcı / denetçinin nasıl çalıştığıdır.
Bergi

Eğer özelliğini kullanıyorsanız JSON.parse(JSON.stringify(obj))olarak da açıklamada söz burada bunun yerine bir dize, nesne şeklinde bir anlık olsun.
Wilt

TL; DR. Yol yolu TL
Rick O'Shea

2

Bu gerçekten sorunun cevabı değil, ancak bu gönderiye rastlayan biri için kullanışlı olabilir ve bir yorum yapmak için çok uzun sürdü:

window.console.logSync = (...args) => {
  try {
    args = args.map((arg) => JSON.parse(JSON.stringify(arg)));
    console.log(...args);
  } catch (error) {
    console.log('Error trying to console.logSync()', ...args);
  }
};

Bu, sözde eşzamanlı bir versiyonunu oluşturur console.log, ancak kabul edilen cevapta belirtilen uyarılarla aynıdır.

Şu anda çoğu tarayıcının console.logbir şekilde eşzamansız olduğu görüldüğünden , bazı senaryolarda bunun gibi bir işlevi kullanmak isteyebilirsiniz.


0

Console.log kullanırken:

a = {}; a.a=1;console.log(a);a.b=function(){};
// without b
a = {}; a.a=1;a.a1=1;a.a2=1;a.a3=1;a.a4=1;a.a5=1;a.a6=1;a.a7=1;a.a8=1;console.log(a);a.b=function(){};
// with b, maybe
a = {}; a.a=function(){};console.log(a);a.b=function(){};
// with b

ilk durumda, nesne yeterince basittir, bu nedenle konsol onu 'dizgilendirebilir' ve sonra size sunabilir; ancak diğer durumlarda, a 'dizgileştirmek' için fazla 'karmaşıktır, bu nedenle konsol size bellek içi nesneyi gösterecektir ve evet, ona baktığınızda b zaten a'ya eklenmiştir.


Bu sorunun 3 yaşında olduğunu biliyorum ama şu anda aynı problemle karşılaşıyorum - nesneyi serileştirmek benim için işe yaramıyor çünkü çok karmaşık. Verilerine erişmeye çalışan bir olayı yakalıyorum, ancak bir şekilde kodda veri yok ama console.log'da veri var.
Skeec
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.