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

Pearl Chen

Giriş

JavaScript'i benzersiz kılan güçlü özelliklerden biri, geri çağırma işlevleri aracılığıyla eşzamansız olarak çalışabilmesidir. Eşzamansız geri çağırma atama, etkinlik odaklı kod yazmanıza olanak tanır ancak JavaScript doğrusal bir şekilde yürütülmediğinden hataları takip etmeyi de can sıkıcı bir deneyim haline getirir.

Neyse ki artık Chrome Geliştirici Araçları'nda, asenkron JavaScript geri çağırmalarının tam çağrı yığınını görüntüleyebilirsiniz.

Eşzamansız çağrı yığınlarına kısa bir genel bakış.
Eş zamansız çağrı yığınlarına kısa bir genel bakış. (Bu demonun akışını kısa süre içinde ayrıntılı olarak açıklayacağız.)

DevTools'da asenkron çağrı yığını özelliğini etkinleştirdikten sonra, web uygulamanızın durumunu farklı zaman noktalarında ayrıntılı olarak inceleyebilirsiniz. Bazı etkinlik dinleyicileri, setInterval,setTimeout, XMLHttpRequest, söz verme işlemleri, requestAnimationFrame, MutationObservers ve daha fazlası için yığın izlemenin tamamını inceleyin.

Yığın izlemeyi takip ederken, çalışma zamanındaki belirli bir yürütme noktasındaki herhangi bir değişkenin değerini de analiz edebilirsiniz. Bu özellik, kol saati kadranlarınız için bir zaman makinesi gibidir.

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

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

Chrome'da etkinleştirerek bu yeni özelliği deneyin. Chrome Canary DevTools'un Kaynaklar paneline gidin.

Sağ taraftaki Çağrı Yığını panelinin yanında "Asenkron" için yeni bir onay kutusu vardır. Asynchronize hata ayıklama özelliğini açmak veya kapatmak için onay kutusunu işaretleyin veya kutunun işaretini kaldırın. (Bununla birlikte, bir kez açtıktan sonra bu özelliği kapatmak istemeyebilirsiniz.)

Asenkron özelliğini etkinleştirin veya devre dışı bırakın.

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

Bu mesajı daha önce Gmail'de görmüş olabilirsiniz:

Gmail, e-posta göndermeyi yeniden deniyor.

İsteği gönderirken bir sorun oluşursa (sunucu veya istemci tarafında ağ bağlantısı sorunları varsa) Gmail, kısa bir zaman aşımından sonra iletiyi otomatik olarak yeniden göndermeyi dener.

Asynkron çağrı yığınlarının gecikmeli zamanlayıcı etkinliklerini ve XHR yanıtlarını analiz etmemize nasıl yardımcı olabileceğini görmek için bu akışı taklit Gmail örneği ile yeniden oluşturdum. JavaScript kodunun tamamını yukarıdaki bağlantıda bulabilirsiniz. Akış aşağıdaki gibidir:

Sahte Gmail örneğinin akış şeması.
Yukarıdaki şemada mavi renkle vurgulanan yöntemler, bu yeni DevTool özelliğinin en yararlı olduğu yerlerdir. Bu yöntemler asenkron olarak çalıştığından bu özellikten en iyi şekilde yararlanmak için bu yöntemlerden yararlanabilirsiniz.

DevTools'un önceki sürümlerinde yalnızca Çağrı Yığını paneline bakarak postOnFail() içindeki bir kesme noktası, postOnFail()'ün nereden çağrıldığı hakkında çok az bilgi verirdi. Ancak, asenkron yığınları etkinleştirdiğinizde ortaya çıkan farka bakın:

Önce
Arayüz Gmail örneğinde, arayüz çağrı yığınları olmadan ayarlanan kesme noktası.
Eşzamansız çağrı etkinleştirilmemiş olarak çağrı yığını paneli.

Burada, postOnFail()'ün bir AJAX geri aramasından başlatıldığını ancak daha fazla bilgi olmadığını görebilirsiniz.

Sonra
Arayüz Gmail örneğinde ayarlanan ve arayüz çağrı yığınları içeren kesme noktası.
Eşzamansız özelliği etkinleştirilmiş Çağrı Grubu paneli.

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

Asenkron çağrı yığınları etkinken, isteğin submitHandler()'ten (gönder düğmesi tıklandıktan sonra gerçekleşir) mi yoksa retrySubmit()'ten (setTimeout() gecikmesinden sonra gerçekleşir) mi başlatıldığını kolayca görmek için çağrı yığınının tamamını görüntüleyebilirsiniz:

submitHandler()
Asenkron çağrı yığınları içeren örnek Gmail'de ayarlanan kesme noktası
retrySubmit()
Arayüz Gmail örneğinde ayarlanan ve arayüz çağrı yığınları olan başka bir kesme noktası

İzleme ifadelerini eşzamansız olarak izleme

Tam çağrı yığınını izlediğinizde, izlenen ifadeleriniz de o andaki durumu yansıtacak şekilde güncellenir.

Asynchronize çağrı yığınlarıyla izleme ifadelerini kullanma örneği

Geçmiş kapsamlardaki kodu değerlendirme

İfadeleri yalnızca izlemenin yanı sıra, önceki kapsamlardaki kodunuzla doğrudan DevTools JavaScript konsol panelinde etkileşim kurabilirsiniz.

Dr. Who olduğunuzu ve Tardis'e girmeden önceki saatle "şimdiki" saati karşılaştırmak için biraz yardıma ihtiyacınız olduğunu düşünün. DevTools konsolundan farklı yürütme noktalarındaki değerleri kolayca değerlendirebilir, saklayabilir ve bunlar üzerinde hesaplamalar yapabilirsiniz.

JavaScript konsolunu asynkron çağrı yığınlarıyla kullanma örneği.
JavaScript konsolunu, kodunuzda hata ayıklama için 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 kalarak kaynak kodunuza geri dönmek, düzenleme yapmak ve tarayıcıyı yenilemek zorunda kalmazsınız.

Zincirlenmiş söz çözümlerini çözme

Önceki Gmail akışının, asenkron çağrı yığını özelliği etkinleştirilmeden anlaşılmasının zor olduğunu düşünüyorsanız zincirlenmiş sözler gibi daha karmaşık asenkron akışların ne kadar zor olacağını tahmin edebiliyor musunuz? Jake Archibald'ın JavaScript Promise'leri konulu eğitici makalesinin son örneğine tekrar göz atalım.

Jake'in async-best-example.html örneğindeki çağrı yığınlarını incelemeyi gösteren küçük bir animasyon verilmiştir.

Önce
Promises örneğinde ayarlanan ve ayarlanmayan kesinti noktası
Eşzamansız çağrı etkinleştirilmemiş olarak çağrı yığını paneli.

Sözleşmelerde hata ayıklama işlemi yaparken Çağrı Yığını panelinde çok az bilgi olduğunu fark edin.

Sonra
Asynchronize çağrı yığınları içeren promises örneğinde ayarlanan kesme noktası.
Eşzamansız özelliği etkinleştirilmiş Çağrı Grubu paneli.

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

Web animasyonlarınızla ilgili analizler alma

HTML5Rocks arşivlerini daha ayrıntılı inceleyelim. Paul Lewis'in requestAnimationFrame ile Daha Hafif, Daha Güçlü ve Daha Hızlı Animasyonlar başlıklı makalesini hatırlıyor musunuz?

requestAnimationFrame demosunu açın ve post.html dosyasının update() yönteminin başına (874. satır civarında) bir kesme noktası ekleyin. Asenkron çağrı yığınları sayesinde, kaydırma etkinliğini başlatan geri çağırma işlevine kadar tüm yolu geri yürüyebilme olanağı da dahil olmak üzere requestAnimationFrame hakkında çok daha fazla analiz elde ederiz.

Önce
Eş zamansız çağrı yığınları olmadan requestAnimationFrame örneğinde ayarlanan kesme noktası.
Eşzamansız çağrı etkinleştirilmemiş olarak çağrı yığını paneli.
Sonra
Eş zamansız çağrı yığınları içeren requestAnimationFrame örneğinde ayarlanan kesme noktası
Ve eşzamansız etkinleştirilmiş halde.

MutationObserver kullanırken DOM güncellemelerini takip etme

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

demo.html dosyasının nodeAdded() (31. satır) içine bir kesme noktası ekleyin. Asynkron çağrı yığınları etkinleştirildiğinde, çağrı yığınını addNode() üzerinden ilk tıklama etkinliğine geri götürebilirsiniz.

Önce
mutationObserver örneğinde, ayarlanan kesme noktası, ayarsız çağrı yığınları olmadan.
Eşzamansız çağrı etkinleştirilmemiş olarak çağrı yığını paneli.
Sonra
Asynchronize çağrı yığınları içeren mutationObserver örneğinde ayarlanan kesme noktası.
Ve eşzamansız etkinleştirilmiş halde.

Eş zamansız çağrı yığınlarında JavaScript'de hata ayıklamayla ilgili ipuçları

İşlevlerinize ad verme

Tüm geri çağırmalarınızı anonim işlev olarak atamaya eğilimliyseniz çağrı yığınını görüntülemeyi kolaylaştırmak için bunlara bir ad verebilirsiniz.

Örneğin, şu anonim işlevi ele alalım:

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

Ardından, windowLoaded() gibi bir ad verin:

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

load etkinliği tetiklendiğinde DevTools yığın izlemesinde "(anonim işlev)" yerine işlev adıyla gösterilir. Bu sayede, yığın izlemenizde neler olduğunu bir bakışta çok daha kolay görebilirsiniz.

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

Daha fazlasını keşfedin

Özetlemek gerekirse, DevTools'un tam çağrı yığınını görüntüleyeceği tüm ayarsız geri çağırma işlevleri şunlardır:

  • Zamanlayıcılar: setTimeout() veya setInterval()'ın başlatıldığı yere geri dönün.
  • XHR'ler: xhr.send() işlevinin çağrıldığı yere geri dönün.
  • Animasyon kareleri: requestAnimationFrame işlevinin çağrıldığı yere geri dönün.
  • Sözler: Bir sözün çözüme ulaştırıldığı yere geri dönün.
  • Object.observe: İzleyici geri çağırma işlevinin orijinal olarak bağlandığı yere geri dönün.
  • MutationObservers: Mutasyon gözlemci etkinliğinin tetiklendiği yere geri dönün.
  • window.postMessage(): İşlem içi mesajlaşma çağrılarını inceleyin.
  • DataTransferItem.getAsString()
  • FileSystem API
  • IndexedDB
  • WebSQL
  • addEventListener() aracılığıyla uygun DOM etkinlikleri: Etkinliğin tetiklendiği yere geri dönün. Performans nedeniyle, tüm DOM etkinlikleri asynkron çağrı yığınları özelliği için uygun değildir. Şu anda kullanılabilen etkinliklere örnek olarak şunlar verilebilir: "scroll", "hashchange" ve "selectionchange".
  • addEventListener() aracılığıyla 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 izlemesini görebilmeniz, kafanızın yanmaya devam etmesini önleyecektir. DevTools'taki bu özellik, özellikle birden fazla asynkron etkinliğin birbiriyle ilişkili olarak gerçekleştiği veya asynkron geri çağırma işlevi içinde yakalanmayan bir istisna atıldığında faydalı olur.

Chrome'da deneyebilirsiniz. Bu yeni özellikle ilgili geri bildiriminiz varsa Chrome Geliştirici Araçları hata takipçisinde veya Chrome Geliştirici Araçları Grubu'nda bize ulaşabilirsiniz.