Chrome Geliştirici Araçları ile eşzamansız JavaScript hatalarını ayıklama

Pearl Chen

Giriş

JavaScript'i benzersiz yapan güçlü bir özellik, geri çağırma işlevleri aracılığıyla eşzamansız olarak çalışabilmesidir. Eş zamansız geri çağırmalar atamak, etkinlik odaklı kod yazmanıza olanak tanır ancak JavaScript doğrusal bir şekilde çalışmadığı için hataların izlenmesini de bir saç çekme deneyimi haline getirir.

Neyse ki artık Chrome Geliştirici Araçları'nda, eşzamansız JavaScript geri çağırmalarının tam çağrı yığınını görebilirsiniz.

Eş zamansız çağrı yığınlarına hızlı bir genel bakış.
Eş zamansız çağrı yığınlarına hızlı bir genel bakış. (Bu demonun akışını yakında inceleyeceğiz.)

Geliştirici Araçları'nda eşzamansız çağrı yığını özelliğini etkinleştirdikten sonra, web uygulamanızın durumunu çeşitli noktalarda ayrıntılı olarak inceleyebilirsiniz. Bazı etkinlik işleyiciler, setInterval,setTimeout, XMLHttpRequest, taahhütler, requestAnimationFrame, MutationObservers ve daha fazlası için tam yığın izlemeyi (stack trace) inceleyin.

Yığın izlemeyi yürütürken, çalışma zamanı yürütme noktasında herhangi bir değişkenin değerini de analiz edebilirsiniz. Bu, kol saati ifadeleriniz için bir zaman makinesi gibi!

Şimdi bu özelliği etkinleştirelim ve bu senaryolardan birkaçına göz atalım.

Chrome'da eş zamansız hata ayıklamayı etkinleştir

Bu yeni özelliği Chrome'da etkinleştirerek deneyin. Chrome Canary Geliştirici Araçları'nın Kaynaklar paneline gidin.

Sağ taraftaki Arama Grubu panelinin yanında, "Eş zamansız" için yeni bir onay kutusu bulunur. Eş zamansız hata ayıklamayı etkinleştirmek veya devre dışı bırakmak için onay kutusunu işaretleyin. (Açıldıktan sonra bu özelliği devre dışı bırakmak istemeyebilirsiniz.)

Eş zamansız özelliğini açın veya kapatın.

Gecikmeli zamanlayıcı etkinliklerini ve XHR yanıtlarını yakalayın

Bunu Gmail'de daha önce görmüşsünüzdür:

Gmail, e-posta göndermeyi yeniden deniyor.

İsteğin gönderilmesiyle ilgili sorun yaşanırsa (sunucuda sorun veya istemci tarafında ağ bağlantısı sorunları varsa) Gmail, kısa bir zaman aşımı süresinin ardından otomatik olarak iletiyi yeniden göndermeyi dener.

Eş zamansız çağrı yığınlarının, geciken zamanlayıcı etkinliklerini ve XHR yanıtlarını analiz etmemize nasıl yardımcı olabileceğini görmek için bu akışı örnek bir Gmail örneği ile yeniden oluşturdum. JavaScript kodunun tamamı yukarıdaki bağlantıda bulunabilir. Ancak akış şu şekildedir:

Gmail örneğinin akış grafiği.
Yukarıdaki şemada, maviyle vurgulanan yöntemler, bu yeni Geliştirici Araçları özelliği eşzamansız olarak çalıştığından en faydalı olacaklardır.

Yalnızca Geliştirici Araçları'nın önceki sürümlerindeki Çağrı Grubu paneline bakarak postOnFail() içindeki bir ayrılma noktası, postOnFail() ürününün nereden çağrıldığı hakkında çok az bilgi verir. Ancak eşzamansız yığınları etkinleştirirken dikkat edin:

Önce
Eş zamansız çağrı yığınları içermeyen örnek Gmail örneğinde ayarlanmış ayrılma noktası.
Eş zamansız senkronizasyon etkinleştirilmeden olmayan Arama Yığını paneli.

Burada, postOnFail() işleminin AJAX geri çağırmasından başlatıldığını ancak başka bilginin olmadığını görebilirsiniz.

Sonra
Eş zamansız çağrı yığınlarına sahip örnek Gmail örneğinde belirlenen ayrılma noktası.
Eş zamansızlığın etkin olduğu Arama Grubu paneli.

Burada XHR'nin submitHandler() kaynağından başlatıldığını görebilirsiniz. Güzel!

Eş zamansız çağrı yığınları etkinken, isteğin submitHandler() kaynağından mı (gönder düğmesini tıkladıktan sonra gerçekleşir) mi yoksa retrySubmit() kaynağından mı (setTimeout() gecikme sonrasında gerçekleşir) başlatıldığını kolayca görmek için çağrı yığınının tamamını görüntüleyebilirsiniz:

submitHandler()
Eş zamansız çağrı yığınlarına sahip örnek Gmail örneğinde belirlenen ayrılma noktası
retrySubmit()
Eş zamansız çağrı yığınlarına sahip örnek Gmail örneğinde ayarlanmış başka bir ayrılma noktası

İfadeleri eşzamansız olarak izleme

Tüm çağrı yığınında gezindiğinizde izlenen ifadeleriniz de o zamanki durumu yansıtacak şekilde güncellenir.

Aysnc çağrı yığınlarıyla kol saati ifadeleri kullanmaya dair örnek

Eski kapsamlardaki kodu değerlendirin

İfadeleri izlemenin yanı sıra doğrudan Geliştirici Araçları JavaScript konsolu panelinden de önceki kapsamlardan kodunuzla etkileşim kurabilirsiniz.

Dr. olduğunuzu hayal edin ve Tardis'e girmeden önceki saati "şimdi" ile karşılaştırmak için biraz yardıma ihtiyacınız var. Geliştirici Araçları konsolundan, farklı yürütme noktalarındaki değerleri kolayca değerlendirebilir, depolayabilir ve kullanabilirsiniz.

JavaScript konsolunu aysnc çağrı yığınlarıyla kullanma örneği.
Kodunuzdaki hataları ayıklamak için JavaScript konsolunu eşzamansız çağrı yığınlarıyla birlikte kullanın. Yukarıdaki demoyu burada bulabilirsiniz.

İfadelerinizi değiştirmek için Geliştirici Araçları'nda kalmak, kaynak kodunuza geri dönme, düzenleme yapma ve tarayıcıyı yenileme zorunluluğunu ortadan kaldırarak size zaman kazandırır.

Zincirleme vaat edilen çözümleri keşfedin

Eş zamansız çağrı yığını özelliği etkinleştirilmeden önceki örnek Gmail akışının çözülmesinin zor olduğunu düşünüyorsanız zincirleme vaatler gibi daha karmaşık eşzamansız akışlar söz konusu olduğunda bunun ne kadar zor olacağını düşünebilir misiniz? Jake Archibald'ın JavaScript Promise ile ilgili eğiticisinin son örneğine tekrar bakalım.

Burada, Jake'in async-best-example.html örneğinde çağrı yığınlarını yürütmeye ilişkin küçük bir animasyon verilmiştir.

Önce
Vaatler örneğinde ayarlanan ayrılma noktası, eşzamansız çağrı yığınları olmadan
Eş zamansız senkronizasyon etkinleştirilmeden olmayan Arama Yığını paneli.

Vaatlerde hata ayıklamaya çalışırken Arama Yığını panelinin bilgi açısından ne kadar kısa olduğuna dikkat edin.

Sonra
Vaatler örneğinde, eş zamansız çağrı yığınlarıyla belirlenen ayrılma noktası.
Eş zamansızlığın etkin olduğu Arama Grubu paneli.

İnanılmaz! Bu tür vaatler. Çok sayıda geri arama.

Web animasyonlarınızla ilgili ayrıntılı bilgi edinin

HTML5Rocks arşivlerini daha yakından inceleyelim. Paul Lewis'in İstekAnimationFrame ile Yalın, Meaner, Faster Animations'ı hatırlıyor musunuz?

requestAnimationFrame demosunu açın ve post.html'nin update() yönteminin başına (874. satır civarında) bir ayrılma noktası ekleyin. Eş zamansız çağrı yığınları sayesinde, başlatılan kaydırma etkinliği geri çağırmasına kadar geri gitme olanağı da dahil olmak üzere requestAnimationFrame hakkında çok daha fazla analiz elde ediyoruz.

Önce
Eş zamansız çağrı yığınları olmadan requestAnimationFrame örneğinde ayarlanan ayrılma noktası.
Eş zamansız senkronizasyon etkinleştirilmeden olmayan Arama Yığını paneli.
Sonra
Eş zamansız çağrı yığınlarıyla requestAnimationFrame örneğinde ayarlanan ayrılma noktası
Ve eşzamansız mod etkinken.

MutationObserver kullanırken DOM güncellemelerini izleme

MutationObserver, DOM'deki değişiklikleri gözlemlememize olanak tanır. Bu basit örnekte, düğmeyi tıkladığınızda <div class="rows"></div> öğesine yeni bir DOM düğümü eklenir.

demo.html'nin nodeAdded() alanına (31. satır) bir ayrılma noktası ekleyin. Eş zamansız çağrı yığınları etkinleştirildiğinde, çağrı yığınını addNode() üzerinden tekrar ilk tıklama etkinliğine yönlendirebilirsiniz.

Önce
MutationObserver örneğinde eşzamansız çağrı yığınları olmadan ayarlanan kesme noktası.
Eş zamansız senkronizasyon etkinleştirilmeden olmayan Arama Yığını paneli.
Sonra
Eş zamansız çağrı yığınlarıyla mutationObserver örneğinde ayarlanan kesme noktası.
Ve eşzamansız mod etkinken.

Eş zamansız çağrı yığınlarında JavaScript'te hata ayıklama ipuçları

İşlevlerinizi adlandırın

Geri aramalarınızın tümünü anonim işlevler olarak atama eğilimindeyseniz çağrı yığınını görüntülemeyi kolaylaştırmak için bunlara bir ad vermek isteyebilirsiniz.

Örneğin, aşağıdaki gibi anonim bir işlev alın:

window.addEventListener('load', function() {
  // do something
});

windowLoaded() gibi bir ad da ver:

window.addEventListener('load', function <strong>windowLoaded</strong>(){
  // do something
});

Yükleme etkinliği tetiklendiğinde, DevTools yığın izlemede şifreli "(anonim işlev)" yerine işlev adıyla birlikte gösterilir. Bu da yığın izinizde neler olup bittiğini bir bakışta görmenizi çok daha kolay hale getirir.

Önce
Anonim bir işlev.
Sonra
Adlandırılmış işlev

Daha fazlasını keşfedin

Özetlemek gerekirse, Geliştirici Araçları'nın tüm çağrı yığınını gösterdiği eşzamansız geri çağırmaların tümü aşağıda verilmiştir:

  • Zamanlayıcılar: setTimeout() veya setInterval() uygulamasının başlatıldığı yere geri dönün.
  • XHR'ler: xhr.send() adlı cihazın çağrıldığı yere geri dönün.
  • Animasyon kareleri: requestAnimationFrame adlı kullanıcının çağrıldığı yere geri dönün.
  • Vaatler: Vaatin sonuca ulaştırıldığı noktaya geri dönün.
  • Object.observe: Gözlemci geri çağırmasının başlangıçta sınırlandığı yere geri dönün.
  • MutationObservers: Mutasyon gözlemleyici etkinliğinin tetiklendiği yere geri dönün.
  • window.postMessage(): İşlem içi mesajlaşma çağrılarını gözden geçirin.
  • DataTransferItem.getAsString()
  • FileSystem API
  • IndexedDB
  • WebSQL
  • addEventListener() üzerinden uygun DOM etkinlikleri: Etkinliğin tetiklendiği yere geri dönün. Performans nedeniyle, bazı DOM etkinlikleri eşzamansız çağrı yığınları özelliği için uygun değildir. Şu anda kullanılabilen etkinliklere örnek olarak "scroll", "hashchange" ve "selectionchange" verilebilir.
  • addEventListener() üzerinden multimedya etkinlikleri: Etkinliğin tetiklendiği yere geri dönün. Kullanılabilir multimedya etkinlikleri şunlardır: ses ve video etkinlikleri (ör. "play", "pause", "ratechange"), WebRTC MediaStreamTrackList etkinlikleri (ör. "addtrack", "removetrack") ve MediaSource etkinlikleri (ör. "sourceopen").

JavaScript geri çağırmalarınızın tam yığın izlemeyi (stack trace) görebilmek, tüm tüyleri kafanızda tutmalıdır. Geliştirici Araçları'ndaki bu özellik, özellikle birbiriyle ilişkili olarak birden fazla eşzamansız etkinlik gerçekleştiğinde veya eşzamansız bir geri çağırma içinden yakalanmamış bir istisna atıldığında faydalı olacaktır.

Chrome'da deneyin. Bu yeni özellikle ilgili geri bildirimleriniz varsa Chrome Geliştirici Araçları hata izleyicisinde veya Chrome Geliştirici Araçları Grubu'nda bize yazın.