Pengantar
Fitur canggih yang membuat JavaScript unik adalah kemampuannya untuk bekerja secara asinkron melalui fungsi callback. Dengan menetapkan callback asinkron, Anda dapat menulis kode berdasarkan peristiwa, tetapi juga menjadikan pelacakan bug menjadi pengalaman menarik karena JavaScript tidak dieksekusi secara linier.
Untungnya, kini di Chrome DevTools, Anda dapat melihat stack panggilan lengkap dari callback JavaScript asinkron.
Setelah mengaktifkan fitur async call stack di DevTools, Anda akan dapat
melihat status aplikasi web pada berbagai waktu. Telusuri stack trace lengkap untuk beberapa pemroses peristiwa, setInterval
,setTimeout
, XMLHttpRequest
, promise, requestAnimationFrame
, MutationObservers
, dan lainnya.
Saat menjalankan pelacakan tumpukan, Anda juga dapat menganalisis nilai variabel apa pun pada titik eksekusi runtime tertentu. Ini seperti mesin waktu untuk ekspresi smartwatch Anda!
Mari kita aktifkan fitur ini dan lihat beberapa skenario berikut.
Mengaktifkan proses debug asinkron di Chrome
Coba fitur baru ini dengan mengaktifkannya di Chrome. Buka panel Sources di Chrome Canary DevTools.
Di samping panel Call Stack di sisi kanan, ada kotak centang baru untuk "Async". Gunakan kotak centang untuk mengaktifkan atau menonaktifkan proses debug asinkron. (Meskipun sudah aktif, Anda mungkin tidak ingin menonaktifkannya.)
Mengambil peristiwa timer yang tertunda dan respons XHR
Anda mungkin pernah melihat ini sebelumnya di Gmail:
Jika ada masalah saat mengirim permintaan (baik server mengalami masalah atau ada masalah konektivitas jaringan di sisi klien), Gmail akan otomatis mencoba mengirim ulang pesan setelah waktu tunggu singkat habis.
Untuk melihat bagaimana stack panggilan asinkron dapat membantu kita menganalisis peristiwa timer yang tertunda dan respons XHR, saya telah membuat ulang alur tersebut dengan contoh Gmail tiruan. Kode JavaScript lengkap dapat ditemukan di link di atas, tetapi alurnya adalah sebagai berikut:
Dengan hanya melihat panel Call Stack di DevTools versi sebelumnya, titik henti sementara dalam postOnFail()
akan memberi Anda sedikit informasi tentang tempat
postOnFail()
dipanggil. Namun, lihat perbedaannya saat mengaktifkan
stack asinkron:
Dengan mengaktifkan stack panggilan asinkron, Anda dapat melihat seluruh stack panggilan untuk dengan mudah
melihat apakah permintaan dimulai dari submitHandler()
(yang terjadi setelah mengklik tombol kirim) atau dari
retrySubmit()
(yang terjadi setelah penundaan setTimeout()
):
Ekspresi smartwatch secara asinkron
Saat Anda menjalankan stack panggilan lengkap, ekspresi yang dipantau juga akan diperbarui untuk mencerminkan status saat itu juga.
Mengevaluasi kode dari cakupan sebelumnya
Selain hanya mengamati ekspresi, Anda bisa berinteraksi dengan kode dari cakupan sebelumnya langsung di panel konsol JavaScript DevTools.
Bayangkan Anda adalah Dr. Who dan Anda perlu sedikit bantuan untuk membandingkan jam dari sebelum Anda masuk ke Tardis dengan "sekarang". Dari konsol DevTools, Anda bisa dengan mudah mengevaluasi, menyimpan, dan melakukan perhitungan nilai dari berbagai titik eksekusi yang berbeda.
Tetap di dalam DevTools untuk memanipulasi ekspresi akan menghemat waktu Anda karena tidak harus beralih kembali ke kode sumber, mengedit, dan memuat ulang browser.
Mengurai resolusi promise yang dirantai
Jika Anda merasa alur Gmail tiruan sebelumnya akan sulit diuraikan tanpa mengaktifkan fitur stack panggilan asinkron, dapatkah Anda membayangkan betapa sulitnya dengan alur asinkron yang lebih kompleks seperti promise yang dirantai? Mari kita lihat kembali contoh terakhir tutorial Jake Archibald tentang JavaScript Promise.
Berikut ini adalah sedikit animasi menjalankan stack panggilan di contoh async-best-example.html Jake.
Dapatkan insight tentang animasi web Anda
Mari kita masuk lebih dalam ke arsip HTML5Rocks. Ingat karya Paul Lewis Leaner, Meaner, quick Animations with requestAnimationFrame?
Buka demo requestAnimationFrame dan tambahkan titik henti sementara di awal metode update() (sekitar baris 874) post.html. Dengan stack panggilan asinkron, kita mendapatkan lebih banyak insight tentang requestAnimationFrame, termasuk kemampuan untuk kembali ke callback peristiwa scroll yang dimulai.
Melacak pembaruan DOM saat menggunakan MutationObserver
MutationObserver
memungkinkan kita untuk mengamati perubahan dalam DOM. Dalam contoh sederhana ini,
saat Anda mengklik tombol, node DOM baru akan ditambahkan ke <div class="rows"></div>
.
Tambahkan titik henti sementara dalam nodeAdded()
(baris 31) di demo.html. Dengan mengaktifkan stack panggilan
asinkron, Anda kini dapat menjalankan stack panggilan kembali melalui addNode()
ke
peristiwa klik awal.
Tips untuk men-debug JavaScript dalam stack panggilan asinkron
Beri nama fungsi Anda
Jika Anda cenderung menetapkan semua callback sebagai fungsi anonim, sebaiknya beri nama callback untuk memudahkan tampilan stack panggilan.
Misalnya, ambil fungsi anonim seperti ini:
window.addEventListener('load', function() {
// do something
});
Lalu, beri nama seperti windowLoaded()
:
window.addEventListener('load', function <strong>windowLoaded</strong>(){
// do something
});
Saat diaktifkan, peristiwa pemuatan akan muncul di stack trace DevTools dengan nama fungsinya, bukan "(anonymous function)" samar. Hal ini sangat memudahkan Anda untuk melihat sekilas apa yang terjadi dalam pelacakan tumpukan.
Jelajahi lebih lanjut
Singkatnya, ini adalah semua callback asinkron tempat DevTools akan menampilkan stack panggilan lengkap:
- Timer:
Kembali ke tempat
setTimeout()
atausetInterval()
diinisialisasi. - XHR:
Kembali ke tempat
xhr.send()
dipanggil. - Frame animasi:
Kembali ke tempat
requestAnimationFrame
dipanggil. - Promise: Kembali ke promise yang telah diselesaikan.
- Object.observe: Kembali ke tempat callback observer awalnya terikat.
- MutationObservers: Kembali ke tempat peristiwa pengamat mutasi diaktifkan.
- window.postMessage(): Berjalanlah melalui panggilan pesan intra-proses.
- DataTransferItem.getAsString()
- API FileSystem
- IndexedDB
- WebSQL
- Peristiwa DOM yang memenuhi syarat melalui
addEventListener()
: Kembali ke tempat peristiwa diaktifkan. Karena alasan performa, tidak semua peristiwa DOM memenuhi syarat untuk fitur async call stack. Contoh peristiwa yang tersedia saat ini meliputi: 'scroll', 'hashchange', dan 'selectionchange'. - Peristiwa multimedia melalui
addEventListener()
: Kembali ke tempat peristiwa diaktifkan. Peristiwa multimedia yang tersedia mencakup: peristiwa audio dan video (misalnya 'play', 'pause', 'ratechange'), peristiwa WebRTC MediaStreamTrackList (misalnya, 'addtrack', 'removetrack'), dan peristiwa MediaSource (misalnya 'sourceopen').
Kemampuan melihat stack trace lengkap callback JavaScript akan membuat Anda tetap tenang. Fitur ini di DevTools akan sangat membantu saat beberapa peristiwa asinkron terjadi dalam kaitannya satu sama lain, atau jika pengecualian yang tidak tertangkap dilempar dari dalam callback asinkron.
Cobalah di Chrome. Jika Anda memiliki masukan tentang fitur baru ini, sampaikan kepada kami di pelacak bug Chrome DevTools atau di Grup Chrome DevTools.