Stroj času k ladění asynchroního JavaScriptu v Chrome DevTools

Vývojářské nástroje v Google Chrome přináší zajímavou novinku. Jedná se o stroj času, pomocí kterého můžete snadno ladit ajaxová volání, resp. procházet různými stavy vaší aplikace v čase pomocí zásobníku asynchronních volání.
Nálepky:
Tento článek je překladem textu Debugging Asynchronous JavaScript with Chrome DevTools od Pearl Chen a je zveřejněn pod licencí CC BY 3.0.
Úvod
Asynchronní zpracování pomocí callback funkcí je mocnou stránkou JavaScriptu, ale současně se dost špatně ladí.
Naštěstí Chrome Canary DevTools přináší řešení, můžete v něm vidět celý zásobník javascriptových asynchronních volání!

Jakmile povolíte zásobník asynchronních volání v DevTools, můžete se nořit do různých stavů vaší webové aplikace v čase. Můžete procházet celý zásobník handlerů událostí, volání setInterval
, setTimeout
, XMLHttpRequest
, promises, requestAnimationFrame
, MutationObservers
a další.
Jak budete zásobníkem volání procházet, můžete současně analyzovat hodnoty jakékoliv proměnné v daném bodě spuštění vaší aplikace. Funguje to podobně jako stroj času.
Pojďme se podívat na několik scénářů použití.
Jak povolit asynchronní ladění v Chrome Canary
Použijte Chrome Canary (build 35 nebo vyšší). Zobrazte si panel Sources v DevTools.
Hned vedle panelu Call Stack napravo najdete checkbox „Async“. Ten asynchronní ladění zapíná a vypíná.

Zachytávání událostí časovače a XHR odpovědí
Nejspíš jste něco podobného v Gmailu už viděli:

Pokud nastane problém při odesílání požadavku (ať už je problém na serveru nebo v síťové konektivitě klienta), Gmail se po krátké odmlce automaticky pokusí zprávu poslat znovu.
Abychom si to mohli snadno vyzkoušet, vytvořila jsem mockup Gmailu. Funguje dle schématu:

Pokud se podíváte na obyčejný zásobník volání, tak breakpoint na postOnFail()
vám nic moc nenapoví, odkud byla funkce vyvolána. Zkusme zapnout asynchronní zásobník a hned je jasno:
Předtím:

postOnFail()
je ajaxový callback, ale nic víc.Potom:

submitHandler()
, který byl vyvolán obsluhou události click ze scripts.js. Pěkné!
V celém zásobníku pak uvidíme, že požadavek pochází buď z submitHandler()
jako na obrázku výše anebo z retrySubmit()
jako na obrázku níže:

Ze zásobníku také poznáme, zda byl požadavek vyvolán obsluhou události, např. kliknutím nebo metodou setTimeout()
nebo některou z dalších asynchronních metod.
Sledujte výrazy asynchronně
Při procházení asynchronním zásobníkem můžete sledovat vybrané výrazy (watch expression), které budou zobrazovat hodnotu odpovídající patřičnému stavu aplikace v čase!

Změňte minulost aneb jak vykonat kód v minulých rozsazích působnosti (scopes)
Minulost můžete nejen zkoumat, ale také v ní spouštět váš kód pomocí javascriptové console.
Představte si, že jste Doktorem Who a potřebujete porovnat čas před vstupem do TARDIS a „nyní“. Žádný problém.

Ušetří vám to čas. Můžete zůstat a pracovat v DevTools, místo abyste přepínali do vašich zdrojáků, upravovali je, znovu načítali atd.
Brzy uvidíte: použití se zřetězenými promises
A co teprve, pokud používáte promises. Převezmu finální příklad z tutoriálu Jake Archibalda k javascriptovým promises.
Předtím:

Potom:

Podpora pro promises se objeví brzy (doufejme, že v Chrome 36). Pokud si ji chcete vyzkoušet už dnes, můžete si ji v Chrome 33 nebo Chrome 34 zapnout na stránce chrome://flags/#enable-devtools-experiments
povolením Developer Tools experimentů. Po restartu prohlížeče najdete v nastavení DevTools volbu enable support for async stack traces.
Projděme se animací
Můžeme jít ještě dál. Paul Lewis napsal článek Leaner, Meaner, Faster Animations with requestAnimationFrame. Otevřeme si jeho requestAnimationFrame demo a nastavíme breakpoint na začátek metody update()
method (okolo řádku 874) v post.html.
Předtím:

Potom:

Sledování změn DOMu pomocí MutationObserverů
MutationObserver
nám umožňuje sledovat změny v DOMu. V tomto jednoduchém příkladu je po kliknutí na tlačítko přidán na konec dokumentu <div class="rows"></div>
.
Přidáme breakpoint do metody nodeAdded()
(řádka 31) v demo.html a podíváme se na výsledek.
Předtím:

Potom:

Tipy k ladění asynchronního JavaScriptu
Pojmenujte vaše funkce
Pokud používáte ve vašich callbacích anonymní funkce, můžete je místo toho chtít pojmenovat, což procházení asynchonním zásobníkem dost zjednoduší.
Místo anonymní funkce:
window.addEventListener('load', function(){
// do something
});
Zkuste:
window.addEventListener('load', function windowLoaded(){
// do something
});
A výsledek?
S anonymní funkcí:

S pojmenovanou funkcí:

Shrnutí
Přehled asynchronních callbacků, které můžete sledovat v asynchronním zásobníku:
- Timers: metody setTimeout() a setInterval()
- XHRs: zavolání xhr.send()
- Animation frames: volání requestAnimationFrame.
- Event listeners: vysledování až k addEventListener().
- MutationObservers: sledování, jaká událost je vyvolala.
A brzy přibude podpora pro tato experimentální javascriptová API:
- Promises
- Object.observe
Díky za článek – pěkný.
Jen dvě drobné chybičky:
A jo, díky.
K bodu dva: koukal jsem na to dolní anonymous, ne na horní. Díky.
Předběhl mě tarmaq a odpověděl správně na oba dva body. Nemám co dodat 8-)
Ono by stačilo, aby se články, co jsou překlad, netvářili, že jsou od předkladatele, ale původního autora, a byl by klid. :-)
Jo, už jsme to spolu jednou probírali. Ale pořád jsem nepřišel, jak na to. Máš příklady nějakých magazínů, kde tohle mají vyřešené?
Já zas nechápu, co v tom má být za problém. Spoustu časopisů (I tištěných) uvádí jméno originálního autora a pod článkem jen přidá řádku „přeloženo z…“
U tištěných časopisů to není problém, tam nepočítám žádná omezení se strany redakčních systémů. Překopat stávající autorství v CMS by bylo několik člověkohodin, spíše člověkodní práce, a to práce, která se nijak nezaplatí a (podle mě) ji kromě tebe nikdo moc neocení. Máme tu řadu věcí, které potřebují dokódovat nebo předělat a dost mě trápí, takže až dostanu nějaký vývojářský čas, radši ho využiji na ně. Až bude Zdroják fungovat, jak má, můžete řešit i ty kosmetické věci jako třeba tohle.
Proč překopávat autorství? Stačí k článku přidat parametry se jménem, popisem a fotkou původního autora a pokud jsou vyplněné, tak se vypíší někde tam, kde se vypisuje redakční autor. Třeba nad ním, nebo vedle. To zvládne i ten váš WordPress. Teď když odroluju na konec článku, dozvím se, kdo je Martin Hassman a ani by mě nenapadlo, že autorem článku může být někdo jiný.
A že hned na začátku článku je uvedeno, kdo je originálním autorem, nepomůže?
zkousel jsem to na jednom dizkuznim foru a pri zapnutem ASync neni prohlizec schopen nacist stranku, stale se objevuje znama screen s chybou. takze za me – nelze se na to spolehnout, tudiz vhodne na experimenty
On Google dobře ví, proč to zatím nechává mezi experimenty 8-)
JS callbacky patri vystrelit smerem do slunce, od doby co Kris Kowal napsal „q“ se jim s uspechem vyhybam a Zeme je znova planeta na ktere se da zit.
.done();