Saya sedang membaca Async Javascript oleh Trevor Burnham. Sejauh ini, ini adalah buku yang bagus.
Dia berbicara tentang cuplikan dan console.log ini menjadi 'asinkron' di konsol Safari dan Chrome. Sayangnya saya tidak bisa meniru ini. Ini kodenya:
var obj = {};
console.log(obj);
obj.foo = 'bar';
// my outcome: Object{}; 'bar';
// The book outcome: {foo:bar};
Jika ini asinkron, saya akan mengantisipasi hasilnya adalah hasil buku. console.log () diletakkan di antrian event sampai semua kode dijalankan, lalu dijalankan dan akan memiliki properti bar.
Tampaknya itu berjalan serempak.
Apakah saya menjalankan kode ini salah? Apakah console.log sebenarnya async?
javascript
asynchronous
Halo Dunia
sumber
sumber
console.log()
itu tidak selalu menampilkan nilai sebelumnya. Solusi jika ini terjadi pada Anda adalah mengubah apa pun yang Anda cobaconsole.log()
menjadi string yang tidak dapat diubah sehingga tidak tunduk pada masalah ini. Jadi, dari pengalamanconsole.log()
memiliki beberapa masalah asinkron yang mungkin terkait dengan data marsaling melintasi batas proses. Ini bukan perilaku yang dimaksudkan, tetapi beberapa efek samping dari caraconsole.log()
kerjanya secara internal (saya pribadi menganggapnya sebagai bug).Jawaban:
console.log
tidak terstandarisasi, sehingga perilakunya agak tidak ditentukan, dan dapat diubah dengan mudah dari rilis ke rilis alat pengembang. Buku Anda sepertinya sudah ketinggalan zaman, begitu juga jawaban saya segera.Untuk kode kami, tidak ada bedanya apakah
console.log
async atau tidak, tidak menyediakan jenis panggilan balik atau lebih; dan nilai yang Anda berikan selalu direferensikan dan dihitung pada saat Anda memanggil fungsi tersebut.Kami tidak benar-benar tahu apa yang terjadi kemudian (OK, kami bisa, karena Firebug, Chrome Devtools dan Opera Dragonfly semuanya open source). Konsol perlu menyimpan nilai yang dicatat di suatu tempat, dan itu akan menampilkannya di layar. Rendering pasti akan terjadi secara asinkron (dibatasi hingga pembaruan batas kecepatan), begitu pula interaksi di masa mendatang dengan objek yang dicatat di konsol (seperti memperluas properti objek).
Jadi konsol mungkin akan mengkloning (membuat serial) objek yang bisa berubah yang Anda catat, atau akan menyimpan referensi ke sana. Yang pertama tidak berfungsi dengan baik dengan objek dalam / besar. Juga, setidaknya rendering awal di konsol mungkin akan menunjukkan status "saat ini" dari objek, yaitu saat ia masuk - dalam contoh Anda, Anda lihat
Object {}
.Namun, saat Anda memperluas objek untuk memeriksa propertinya lebih jauh, kemungkinan konsol hanya akan menyimpan referensi ke objek dan propertinya, dan menampilkannya sekarang akan menampilkan status saat ini (sudah bermutasi). Jika Anda mengklik
+
, Anda akan melihatbar
properti dalam contoh Anda.Berikut adalah tangkapan layar yang telah diposting di laporan bug untuk menjelaskan "perbaikan" mereka:
Jadi, beberapa nilai mungkin direferensikan lama setelah dicatat, dan evaluasinya agak lambat ("bila diperlukan"). Contoh paling terkenal dari perbedaan ini ditangani dalam pertanyaan Apakah konsol JavaScript Chrome malas mengevaluasi array?
Solusinya adalah memastikan untuk selalu mencatat snapshot serial dari objek Anda, misalnya dengan melakukan
console.log(JSON.stringify(obj))
. Ini akan bekerja untuk objek non-lingkaran dan agak kecil saja. Lihat juga Bagaimana cara mengubah perilaku default console.log di Safari? .Solusi yang lebih baik adalah dengan menggunakan breakpoint untuk debugging, di mana eksekusi benar-benar berhenti dan Anda dapat memeriksa nilai saat ini di setiap titik. Gunakan logging hanya dengan data yang dapat diserialisasikan dan tidak dapat diubah.
sumber
console.log
masih asinkron di Chrome seperti yang berumur 8 tahun (lihat stackoverflow.com/questions/7389069/… ), satu-satunya hal yang berubah adalah bahwa sekarang Chrome mengeluarkan cuplikan dari objek referensi di kali Anda memanggilconsole.log
(jika Anda memperluas objek yang dicatat, Anda akan melihat properti dan nilai akhirnya setelah operasi mutasi yang Anda lakukan setelahnyaconsole.log
), atauconsole.log
memang sinkron?JSON.parse(JSON.stringify(obj))
seperti yang juga disebutkan dalam komentar di sini Anda mendapatkan snapshot dalam bentuk objek, bukan string.Ini sebenarnya bukan jawaban untuk pertanyaan, tetapi mungkin berguna bagi seseorang yang tersandung pada posting ini, dan itu terlalu panjang untuk memberikan komentar:
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); } };
Ini membuat versi pseudo-sinkronis
console.log
, tetapi dengan peringatan yang sama seperti yang disebutkan dalam jawaban yang diterima.Karena sepertinya, saat ini, sebagian besar browser
console.log
tidak sinkron dalam beberapa hal, Anda mungkin ingin menggunakan fungsi seperti ini dalam skenario tertentu.sumber
Saat menggunakan console.log:
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
dalam situasi pertama, objek cukup sederhana, sehingga konsol dapat 'merangkai' objek tersebut kemudian ditampilkan kepada Anda; tetapi dalam situasi lain, a terlalu 'rumit' untuk 'dirangkai' sehingga konsol akan menampilkan objek dalam memori sebagai gantinya, dan ya, ketika Anda melihatnya b telah dilampirkan ke a.
sumber