italská píseň

zóna plechovky je knihovna, která implementuje zóny.

Zóny jsou abstrakcí, která vám umožňuje psát čistší kód pro různé účely, včetně implementace aplikací vykreslovaných na straně serveru (SSR), profilování, užitečnějšího trasování zásobníku pro ladění nebo čistého způsobu implementace špinavé kontroly.

Tento článek bude:

  • Vysvětlete, co jsou zóny.
  • Vysvětlete, jak funguje can-zone.
  • Zobrazit základní API can-zone.

Zónám může být zpočátku obtížné porozumět, proto se tento článek bude držet základů. Příští týden zveřejním na blog.bitovi.com navazující článek vysvětlující, jak DoneJS používá can-zone k elegantnímu umožnění vykreslování aplikací na straně serveru.

Co jsou zóny?

Jak již víte, JavaScript je asynchronní jazyk. V praxi to znamená, že JavaScriptové stroje obsahují (více) fronty, které používají ke sledování asynchronních úloh, které mají být provedeny později. Chcete-li o tom přemýšlet, podívejte se na jednoduchý příklad asynchronního kódu:

Asynchronní příklad

Tento kód spouští funkci app , který naplánuje funkci logging být volán dvakrát se 2 různými argumenty. Rozdělení toho, co se děje v enginu JavaScript:

  1. Provede se úloha skriptu, která definuje a provede app funkce. setTimeout je volán dvakrát a naplánuje jejich zpětná volání tak, aby se spouštěla ​​po 10 ms.

  2. Po 10 ms bude první úloha odebrána z fronty a spuštěna do dokončení, přičemž se zaznamená 0 ​​až 500.

  3. Po dokončení prvního úkolu bude druhý úkol odebrán z fronty a spuštěn do dokončení. Bude logovat od 0 do 5000.

  4. Fronta úkolů je nyní prázdná.

Chcete-li se hlouběji ponořit do úloh JavaScriptu a mikroúloh, podívejte se na příspěvek Jakea Archibalda na toto téma.

Zóny poskytují způsob, jak se připojit k chování smyčky událostí JavaScriptu. Chcete-li si lépe představit, co se děje ve výše uvedeném kódu, podívejte se, co se stane, když je stejný kód spuštěn v zóně pomocí can-zone.

Zóna před úkolem a po úkolu

Zde máme stejný kód, ale s přidáním protokolování před a po spuštění každé úlohy. Všimněte si, že první dvě věci, které jsou zaznamenány, jsou „beforeTask“ a „afterTask“. Důvodem je spuštění app je samo o sobě úkolem. Poté, když jsou funkce naplánované pomocí setTimeout provedeny "beforeTask" a "afterTask", jsou také zaprotokolovány pro každou z nich.

S tímto stavebním blokem můžeme vytvořit užitečnější abstrakce pro práci s kódem, který běží ve smyčce událostí. Jednou, kterou vám can-zone poskytuje, je schopnost vědět, kdy jsou všechny asynchronní úlohy dokončeny. Každá zóna má přidružený slib, který se vyřeší, když se vyprázdní všechny fronty úkolů.

V následujícím příkladu máme aplikaci, která provádí dva požadavky AJAX na zobrazení seznamů a nahoře čas potřebný k vykreslení. To lze napsat pomocí Promises tím, že počkáte na vyřešení všech slibů, jak je uvedeno níže:

Rámce

S pouze 2 asynchronními úkoly, na které se čeká, to není tak špatné, ale bude se to špatně škálovat, protože kód se stává složitějším (jako kdyby byly požadavky spouštěny jako vedlejší efekt nějakého jiného volání funkce). can-zone nám umožňuje napsat stejný kód, aniž bychom museli ručně sledovat slib každého požadavku:

Rámce II

To nám říká, za jak dlouho se seznamy plně zobrazí, ale můžeme to udělat lépe a víme, jak dlouho to trvalo náš kód skutečně spustit, čímž se z rovnice odstraní latence sítě. Pomocí háčků zóny diskutovaných dříve, před úkolem a po úkolu můžeme měřit pouze čas, ve kterém se náš JavaScript spouští:

Rychlejší zatížení

Tato technika poskytuje pohled na to, proč vykreslení tohoto kódu trvá tak dlouho; není to chyba špatně napsaného kódu, ale problém je spíše latence sítě. S těmito informacemi můžeme provést informativnější optimalizaci pro dobu načítání stránky.

Koncept zón nabírá páru v JavaScriptu. Angular má podobnou knihovnu Zone. Ale zatímco zone.js od Angularu je zaměřen na pomoc při ladění a vylepšování nečistého kontrolního kódu, can-zone se zaměřuje na řešení vykreslování na straně serveru.

Jak funguje can-zone

V budoucnu by Zones mohly být součástí standardu EMCAScript, ale nyní can-zone implementuje chování zabalením funkcí, které spouštějí asynchronní události (včetně XHR, setTimeout, requestAnimationFrame). can-zone nejen zabalí funkce, ale také zaznamená, kdy jsou úkoly dokončeny, a poskytuje API podobné Promise, které vám dá vědět, kdy bylo dokončeno veškeré asynchronní chování.

Výše jsme viděli několik jednoduchých příkladů zón; níže je složitější příklad. Ilustruje to, že i když jsou asynchronní volání vnořena do sebe, can-zone bude čekat, až se vše dokončí.

může zóna

Pod kapotou can-zone přepisuje následující metody:

  • nastavit časový limit
  • vymazat časový limit
  • XMLHttpRequest
  • requestAnimationFrame
  • Slib
  • process.nextTick (v Node)
  • MutationObserver

Nemění to jejich základní chování. Jednoduše zvýší počítadlo, aby sledovalo, kolik zbývá zpětných volání. Čítač se sníží, když jsou tato zpětná volání volána. Když počet dosáhne nuly, příslib zóny je vyřešen.

API a funkce

Jemná kontrola nad tím, který kód vás zajímá

Zone.ignore umožňují uživatelům ignorovat (ne čekat na) určité funkce. Můžete to použít, pokud máte kód provádějící rekurzivní setTimeouts (protože se to nikdy nedokončí) nebo pro nějaké volání API, které není dostatečně důležité, aby se na něj čekalo. Zde je příklad použití:

function recursive(){
  setTimeout(function(){
    recursive();
  }, 20000);
}

var fn = Zone.ignore(recursive);

// This call will not be waited on.
fn();

Zone.waitFor je způsob, jak definovat vlastní asynchronní chování. Můžete si to představit jako opak Zone.ignore . Řekněme, že existují některé asynchronní úlohy, které can-zone ještě neimplementuje, nebo knihovna uzlů s vlastními vazbami C++, která dělá asynchronní věci bez našeho vědomí. Stále můžete zabalit tyto kusy kódu, abyste zajistili, že budou čekat na:

var Zone = require("can-zone");
var fs = require("fs");

module.exports = function(filename) {
  fs.readFile(__dirname + filename, "utf8", Zone.waitFor(function(err, file){
    Zone.current.data.file = file;
  }));
};

Háčky pro životní cyklus

can-zone poskytuje háčky pro zápis kódu, který běží v různých bodech životního cyklu zóny:

  • created – Volá se při prvním vytvoření zóny.
  • skončilo – volá se, když se zóna brzy vyřeší.
  • beforeTask – Volá se před spuštěním každé asynchronní úlohy.
  • afterTask – Volá se po každém spuštění asynchronní úlohy.
  • beforeRun – Volá se bezprostředně před run zóny funkce se provede.

Tyto háčky jsou užitečné při implementaci pluginů. Dříve jsme vytvořili jednoduchý výkonnostní plugin, který používal beforeTask a afterTask k načasování toho, jak dlouho trvalo provedení každé úlohy.

Vytvořte pluginy

funkce konstruktoru can-zone přebírá speciální konfigurační objekt nazvaný ZoneSpec. Objekt ZoneSpec je tam, kde:

  • Vytvářejte zpětná volání pro háky životního cyklu.
  • Zdědit chování z jiných pluginů.
  • Definujte své vlastní háčky, pro které mohou ostatní pluginy (které po vás zdědí) poskytovat zpětná volání.
  • Definujte globální hodnoty, které by měly být přepsány v asynchronních zpětných voláních zóny.

Zde je příklad pluginu, který náhodně mění název vaší stránky.

var titleZone = {
  beforeTask: function(){
    document.title = Math.random() + " huzzah!";
  }
};

var zone = new Zone({
  plugins: [titleZone]
});

can-zone přichází s několika pluginy, které by se vám mohly hodit:

  • can-zone/xhr:Může být použit na serveru a klientovi (za předpokladu, že máte XMLHttpRequest shim pro Node) k poskytování možností ukládání do mezipaměti při vykreslování na straně serveru.
  • can-zone/timeout:Definujte časový limit v milisekundách, kdy bude příslib zóny odmítnut.
  • can-zone/debug:Používá se ve spojení s can-zone/timeout, poskytuje trasování zásobníku každého asynchronního úkolu, který se nepodařilo dokončit během časového limitu.

Další informace

  • Stránka projektu GitHub
  • Příklad SSR can-zone pouze pro jQuery s jQuery
  • Stránka projektu NPM
  • Nainstalujte jej:npm install can-zone