Pengantar
Fitur canggih yang membuat JavaScript unik adalah kemampuannya untuk bekerja secara asinkron melalui fungsi callback. Menetapkan callback asinkron memungkinkan Anda menulis kode berbasis peristiwa, tetapi juga membuat pelacakan bug menjadi pengalaman yang melelahkan karena JavaScript tidak dieksekusi secara linear.
Untungnya, sekarang di Chrome DevTools, Anda dapat melihat stack panggilan lengkap dari callback JavaScript asinkron.
Setelah mengaktifkan fitur stack panggilan asinkron di DevTools, Anda akan dapat
melihat status aplikasi web Anda pada berbagai titik waktu. Ikuti pelacakan tumpukan penuh untuk beberapa pemroses peristiwa, setInterval
,setTimeout
, XMLHttpRequest
, promise, requestAnimationFrame
, MutationObservers
, dan lainnya.
Saat menelusuri stack trace, Anda juga dapat menganalisis nilai variabel apa pun pada titik eksekusi runtime tertentu tersebut. 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, terdapat kotak centang baru untuk "Async". Gunakan kotak centang untuk mengaktifkan atau menonaktifkan proses debug asinkron. (Meskipun setelah diaktifkan, Anda mungkin tidak ingin menonaktifkannya.)
Merekam peristiwa timer yang tertunda dan respons XHR
Anda mungkin pernah melihatnya sebelumnya di Gmail:
Jika ada masalah saat mengirim permintaan (server mengalami masalah atau ada masalah konektivitas jaringan di sisi klien), Gmail akan otomatis mencoba mengirim ulang pesan setelah waktu tunggu singkat.
Untuk melihat cara stack panggilan asinkron dapat membantu kami menganalisis peristiwa timer yang tertunda dan respons XHR, saya telah membuat ulang alur tersebut dengan contoh tiruan Gmail. Kode JavaScript lengkap dapat ditemukan di link di atas, tetapi alurnya adalah sebagai berikut:
Dengan hanya melihat panel Stack Panggilan di versi DevTools 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
melihat dengan mudah apakah permintaan dimulai dari submitHandler()
(yang terjadi setelah mengklik tombol kirim) atau dari
retrySubmit()
(yang terjadi setelah penundaan setTimeout()
):
Menonton ekspresi secara asinkron
Saat Anda menelusuri stack panggilan lengkap, ekspresi yang Anda amati juga akan diperbarui untuk mencerminkan statusnya pada saat itu.
Mengevaluasi kode dari cakupan sebelumnya
Selain sekadar memantau ekspresi, Anda dapat berinteraksi dengan kode dari cakupan sebelumnya langsung di panel konsol JavaScript DevTools.
Bayangkan Anda adalah Dr. Who dan Anda memerlukan sedikit bantuan untuk membandingkan jam dari sebelum Anda masuk ke Tardis hingga "sekarang". Dari konsol DevTools, Anda dapat dengan mudah mengevaluasi, menyimpan, dan melakukan penghitungan pada nilai dari berbagai titik eksekusi.
Tetap berada di dalam DevTools untuk memanipulasi ekspresi akan menghemat waktu Anda karena tidak perlu beralih kembali ke kode sumber, melakukan pengeditan, dan memuat ulang browser.
Mengurai resolusi promise berantai
Jika Anda merasa alur tiruan Gmail sebelumnya sulit dipahami tanpa mengaktifkan fitur stack panggilan asinkron, dapatkah Anda membayangkan betapa lebih sulitnya dengan alur asinkron yang lebih kompleks seperti promise berantai? Mari kita bahas kembali contoh akhir tutorial Jake Archibald tentang Promise JavaScript.
Berikut adalah animasi kecil untuk menelusuri stack panggilan dalam contoh async-best-example.html Jake.
Mendapatkan insight tentang animasi web Anda
Mari kita pelajari lebih dalam arsip HTML5Rocks. Ingat artikel Animasi yang Lebih Ringan, Lebih Efisien, dan Lebih Cepat dengan requestAnimationFrame dari Paul Lewis?
Buka demo requestAnimationFrame dan tambahkan titik henti sementara di awal metode update() (sekitar baris 874) dari post.html. Dengan tumpukan panggilan asinkron, kita mendapatkan lebih banyak insight tentang requestAnimationFrame, termasuk kemampuan untuk melacak seluruh jalan kembali ke callback peristiwa scroll yang memulai.
Melacak update DOM saat menggunakan MutationObserver
MutationObserver
memungkinkan kita mengamati perubahan di 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 tumpukan panggilan
asinkron, Anda kini dapat menelusuri tumpukan panggilan kembali melalui addNode()
ke
peristiwa klik awal.
Tips untuk men-debug JavaScript dalam tumpukan panggilan asinkron
Memberi nama fungsi
Jika cenderung menetapkan semua callback sebagai fungsi anonim, sebaiknya beri nama untuk memudahkan melihat tumpukan 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 pelacakan tumpukan DevTools dengan nama fungsinya, bukan "(anonymous function)" yang samar. Hal ini sangat memudahkan untuk melihat sekilas apa yang terjadi di stack trace Anda.
Mempelajari lebih lanjut
Untuk merangkum, berikut adalah semua callback asinkron tempat DevTools akan menampilkan tumpukan 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 tempat promise telah di-resolve.
- Object.observe: Kembali ke tempat callback observer awalnya terikat.
- MutationObservers: Kembali ke tempat peristiwa observer mutasi diaktifkan.
- window.postMessage(): Menjalankan panggilan pesan intra-proses.
- DataTransferItem.getAsString()
- FileSystem API
- 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 stack panggilan asinkron. Contoh peristiwa yang saat ini tersedia 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 untuk melihat stack trace lengkap dari callback JavaScript akan membuat Anda tidak perlu khawatir. Fitur ini di DevTools akan sangat membantu saat beberapa peristiwa asinkron terjadi dalam hubungan satu sama lain, atau jika pengecualian yang tidak tertangkap ditampilkan dari dalam callback asinkron.
Coba di Chrome. Jika Anda memiliki masukan tentang fitur baru ini, kirimkan email kepada kami di pelacak bug Chrome DevTools atau di Grup Chrome DevTools.