Skip to content

Commit 1ff2316

Browse files
committed
Corecturi finale
1 parent fb8511e commit 1ff2316

File tree

9 files changed

+153
-37
lines changed

9 files changed

+153
-37
lines changed

event-loop-call-stack-callback/callbacks/callback-uri.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,4 +279,5 @@ Dacă un callback trebuie invocat cu întârziere, definește funcția pentru a
279279

280280
## Referințe
281281

282-
- [The Art of Node. An introduction to Node.js](https://github.com/maxogden/art-of-node#callbacks)
282+
- [The Art of Node. An introduction to Node.js](https://github.com/maxogden/art-of-node#callbacks)
283+
- http://callbackhell.com/

functii/functii-async.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Acest enunț a fost introdus în EcmaScript 2017 și face ca o funcție să returneze o promisiune (`Promise`). Funcțiile acestea poartă cuvântul cheie `async` în fața lui `function`. Apariția lor marchează o nouă paradigmă de lucru cu promisiunile.
44

5-
Înainte de apariția acestori funcții, pentru a scrie cod asyncron aveam la îndemână callback-uri și promisiuni. În mod curent, până la apariția async/await ai fi returnat un obiect `Promise` proaspăt instanțiat.
5+
Înainte de apariția acestor funcții, pentru a scrie cod asincron aveam la îndemână callback-uri și promisiuni. În mod curent, până la apariția async/await ai fi returnat un obiect `Promise` proaspăt instanțiat.
66

77
```javascript
88
function simulare () {
@@ -29,14 +29,13 @@ sarcina().then(mesaj => console.log(mesaj));
2929
Să lucrăm cu un caz ceva mai util. Atunci când am discutat despre cum este executat codul JavaScript, am folosit un exemplu
3030

3131
```javascript
32-
TODO: Nu uita să ștergi cheia mea din stringul de acces la API-ul Europeana
3332
// înlocuiește cheia API din link numită wskey, cu una personală obținută
3433
// de la https://pro.europeana.eu/get-api
3534
// Secvența unde vei pune cheia ta este wskey=XXXXXXXXX
3635
// înlocuiește XXXXXXXXX cu propria cheie
3736
// dacă nu introduci cheia personală vei avea o eroare
3837
// Cross-Origin Request Blocked
39-
let adresa = "https://www.europeana.eu/api/v2/search.json?wskey=MH8g7b6hz&query=The%20Fraternity%20between%20Romanian%20and%20French%20Army";
38+
let adresa = "https://www.europeana.eu/api/v2/search.json?wskey=XXXXXXXXX&query=The%20Fraternity%20between%20Romanian%20and%20French%20Army";
4039
function aduMi () {
4140
fetch(adresa)
4241
.then((resursa) => resursa.json())
@@ -49,7 +48,7 @@ aduMi();
4948
Pentru a simplifica putem transforma funcția noastră într-una `async`.
5049

5150
```javascript
52-
let adresa = "https://www.europeana.eu/api/v2/search.json?wskey=MH8g7b6hz&query=The%20Fraternity%20between%20Romanian%20and%20French%20Army";
51+
let adresa = "https://www.europeana.eu/api/v2/search.json?wskey=XXXXXXXXX&query=The%20Fraternity%20between%20Romanian%20and%20French%20Army";
5352
async function aduMi () {
5453
const resursa = await fetch(adresa);
5554
const rezultat = await resursa.json();
@@ -62,6 +61,11 @@ aduMi().then((înregistrarea) => console.log(înregistrarea)).catch(() => consol
6261

6362
Ceea ce permit funcțiile async/await este posibilitatea de a captura toate erorile ridicate de codul asincron, dar și cel sincron. Deci, folosirea unei structuri `try...catch` este valabilă.
6463

64+
## Dependințe cognitive
65+
66+
- iteratori
67+
- generatoare
68+
6569
## Referințe
6670

6771
- [Asynchronous Adventures in JavaScript: Async/Await](https://medium.com/dailyjs/asynchronous-adventures-in-javascript-async-await-bd2e62f37ffd)

functii/generators.md

Lines changed: 111 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Generators
22

3-
Generatoarele oferă posibilitatea de a parcurge o colecție de date. Este un nou tip de funcții introduse în ECMAScript 2015 care *produc* (*yield* în limba engleză) valori la cerere. Punerea unei steluțe după cuvântul cheie `function`, va semnala că avem de a face cu o funcție generator. Funcțiile săgeată nu pot fi iteratori.
3+
Generatoarele oferă posibilitatea de a parcurge o colecție de date. Este un nou tip de funcții introduse în ECMAScript 2015 care *produc* (*yield* în limba engleză) valori la cerere. Punerea unei steluțe după cuvântul cheie `function`, va semnala că avem de a face cu o funcție generator. O funcție generator este ceva mai specială pentru că la momentul invocării sale, nu se execută codul intern, ci este returnat un obiect iterator. Funcțiile săgeată nu pot fi iteratori.
44

55
```javascript
66
function* ceva () {
@@ -17,7 +17,7 @@ x.next(); // încearcă să mai scoți un rezultat
1717

1818
Acest nou tip de lucru cu funcțiile se bazează pe faptul că accesul la date se face cu ajutorul iteratoarelor. Atunci când execuți un generator se creează un nou obiect iterator. Standardul menționează că acest obiect nou generat poate suporta și subclase. Un obiect iterator știe cum să acceseze elementele unei colecții unul după altul până la epuizarea lor. Acest obiect are niște metode disponibile pentru a iniția evaluarea expresiilor după cuvântul cheie `yield`. După evaluare, execuția generatorului se oprește în așteptarea unui nou apel al metodei `next()`. Poți percepe un generator ca un program care se execută la cerere și în etape. Fiecare etapă marcată de `yield` are asociată o stare.
1919

20-
Apelarea unui generator nu îl execută, ci doar este trimisă funcția în stiva apelurilor și imediat este suspendată execuția. De fapt, la apelare este returnat un obiect iterator. Obiectul iterator ține o referință către contextul de execuție al generatorului care este în call-stack. După ce au fost evaluate toate expresiile până la întâlnirea primului `yield`, contextul de execuție al generatorului va fi scos din stiva de apeluri, dar obiectul iterator care s-a creat, va ține minte acest context de execuție. Execuția metodei `next()` nu creează un nou context de execuție precum în cazul clasic, ci doar reactivează contextul de execuție al generatorului pe care-l împinge din nou în callstack. Se continuă execuția de unde a rămas începând cu expresiile de după `yield`. Codul este evaluat până la întâlnirea următorului `yield`, când execuția este suspendată din nou, nu înainte de a actualiza obiectul iterator care ține minte starea - ține viu contextul de execuție. Acest ultim aspect oferă un mare avantaj al generatoarelor pentru că rețin valorile între diferitele etape parcurse cu `next()`.
20+
Apelarea unui generator nu îl execută, ci doar este trimisă funcția în stiva apelurilor și imediat este suspendată execuția, fiind returnat un obiect iterator. Obiectul iterator ține o referință către contextul de execuție al generatorului care este în call-stack. După ce au fost evaluate toate expresiile până la întâlnirea primului `yield`, contextul de execuție al generatorului va fi scos din stiva de apeluri, dar obiectul iterator care s-a creat, va ține minte acest context de execuție. Execuția metodei `next()` nu creează un nou context de execuție precum în cazul clasic, ci doar reactivează contextul de execuție al generatorului pe care-l împinge din nou în callstack. Se continuă execuția de unde a rămas începând cu expresiile de după `yield`. Codul este evaluat până la întâlnirea următorului `yield`, când execuția este suspendată din nou, nu înainte de a actualiza obiectul iterator care ține minte starea - ține viu contextul de execuție. Acest ultim aspect oferă un mare avantaj al generatoarelor pentru că rețin valorile între diferitele etape parcurse cu `next()`.
2121

2222
Dacă în execuție nu mai este întâlnit niciun `yield`, funcția generator returnează obiectul iterator, care în acest moment va avea valoarea `true` asociată cheii `done`.
2323

@@ -32,9 +32,11 @@ var genob = parcurgObiect();
3232
genob.next();
3333
```
3434

35+
Datorită acestui comportament al generatoarelor prin care este permisă întreruperea execuției, în practică mai sunt numite și **corutine**.
36+
3537
## Procesare de generatoare
3638

37-
Funcțiile generator pot procesa alte funcții generator.
39+
Funcțiile generator pot procesa alte funcții generator. Expresia `yield*` este folosită în cazul în care dorești să delegi execuția către un alt generator sau obiect iterator. Asigură-te că expresia care stă după `yield*` este un obiect iterabil. Generatoarele sunt obiecte iterabile pentru că implementează protocoalele `iterable` și `iterator`.
3840

3941
```javascript
4042
function* unGen () {
@@ -49,6 +51,8 @@ for (let obiRet of unGen()) {
4951
};
5052
```
5153

54+
Ceea ce se petrece atunci când `yield*` este aplicat unui obiect iterabil este că va face `yield` pentru toate valorile din obiectul iterabil căruia i se aplică.
55+
5256
## Trimiterea mesajelor
5357

5458
Un lucru foarte interesant care privește funcțiile generator este că se pot trimite mesaje din funcție în obiectul iterator instanțiat și invers.
@@ -326,8 +330,112 @@ for(let element of parcurgDOM(elementDOM)){
326330
};
327331
```
328332

333+
## Corutine
334+
335+
Corutinele sunt un model de organizare a executării funcțiilor care își întrerup execuția pentru a ceda controlul alteia. JavaScript nu are un mecanism dedicat realizării corutinelor. Cel mai apropiat fiind totuși generatoarele care prin `yield`, cedează controlul unui alt context de execuție, iar la momentul oportun își reiau execuția. Corutinele sunt un mecanism care în loc să folosească callback-urile, fac uz de *event loop*.
336+
337+
Pentru a gestiona un generator folosind o corutină, trebuie să elaborezi o funcție *wrapper* suplimentară. Aceasta va gestiona următoarea logică necesară:
338+
339+
- va apela generatorul și va genera obiectul generator;
340+
- va apela metoda `next()` pe obiectul generator ceea ce va conduce la executarea întregului cod până când `yield` apare;
341+
- va apela metoda `next(...)` în care vor fi trimise date către generator.
342+
343+
```javascript
344+
function corutină (funcGenerator) {
345+
var obiectGenerator = funcGenerator(); // instanțierea obiectului
346+
obiectGenerator.next(); // execută codul generatorului până la primul yield
347+
return function (dateDeTrimisÎnGenerator) {
348+
obiectGenerator.next(dateDeTrimisÎnGenerator);
349+
};
350+
};
351+
```
352+
353+
Folosind acest model, funcția *wrapper* oferă mecanismul de interacțiune cu generatorul fără a mai apela metoda `next()` direct pe obiectul generator.
354+
355+
```javascript
356+
var generatorGestionat = corutină (function* gen () {
357+
var primaVal = yield;
358+
console.log('Iese prima valoare la primul yield: ', primaVal);
359+
var aDouaVal = yield;
360+
console.log('Și a doua valoare: ', aDouaVal);
361+
});
362+
generatorGestionat('primo');
363+
generatorGestionat('secundo');
364+
```
365+
366+
Ținta ar fi ca de fiecare dată când se face un `yield`, o funcție să preia efortul de calcul și să ofere un rezultat. Când corutina și-a încheiat propria execuție, apelează la un alt `yield` din generator.
367+
368+
```javascript
369+
function corutine (func) {
370+
var gen = func(); // creezi generatorul și ceri primul yield
371+
gen.next();
372+
return function oVal (valoare) {
373+
gen.next(valoare); // valoare este pasat generatorului
374+
};
375+
};
376+
function* gen1 () {
377+
var intrare; // este valoarea care intră prin argument
378+
intrare = yield;
379+
console.log('primul yield: ', intrare);
380+
intrare = yield;
381+
console.log('al doilea yield: ', intrare);
382+
};
383+
function* gen2 () {
384+
var intrare; // este valoarea care intră prin argument
385+
intrare = yield;
386+
console.log('primul yield din a doua corutină: ', intrare);
387+
intrare = yield;
388+
console.log('al doilea yield din a doua corutină: ', intrare);
389+
};
390+
var x = corutine(gen1); x('ceva'); // primul yield: ceva
391+
var y = corutine(gen2); y('altceva'); // primul yield din a doua corutină: altceva
392+
x('salve'); // al doilea yield: salve
393+
y('eh'); // al doilea yield din a doua corutină: eh
394+
```
395+
396+
Corutinele pot fi folosite și în scenarii în care sunt gestionate promisiuni.
397+
398+
```javascript
399+
var colectie1 = {a: 1, b: 'ceva'},
400+
colectie2 = {x: 'a', y: 10};
401+
402+
var promisiune1 = new Promise(function exec (resolve, reject) {
403+
resolve(colectie1);
404+
});
405+
var promisiune2 = new Promise(function exec (resolve, reject) {
406+
resolve(colectie2);
407+
});
408+
409+
function corutina (functie) {
410+
var generator = functie();
411+
var avanseaza = function salt (date) {
412+
let next = generator.next(date); /**/
413+
if(!next.done){
414+
next.value.then((v) => {
415+
console.log(v);
416+
});
417+
return next.value.then(avanseaza);
418+
};
419+
};
420+
avanseaza();
421+
};
422+
423+
function* generator () {
424+
let promisePool = [promisiune1, promisiune2];
425+
yield Promise.all(promisePool); /**/
426+
};
427+
428+
corutina(generator);
429+
```
430+
329431
## Dependințe cognitive
330432

331433
- funcții,
332434
- iteratori
333435
- `for...of`
436+
437+
## Resurse
438+
439+
- https://www.wptutor.io/web/js/generators-coroutines-async-javascript
440+
- https://x.st/javascript-coroutines/
441+
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*

obiecte/obiecte-interne-standard/Array/introducere-array.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ Mai este un caz al folosirii constructorului în ceea ce privește crearea unui
302302

303303
![](operatiuniArrayuri.svg)
304304

305-
### Array-uri dense prin aplicarea lui `apply()` moștenit de la `Function`.
305+
### Array-uri dense prin aplicarea lui `apply()` moștenit de la `Function`.
306306

307307
Acesta este un truc pentru a genera array-uri de o dimensiune fixă, dar care, în loc de elemente vide la inițiere, va fi populat cu valori `undefined`. Se folosește `Function.prototype.apply()`, care se poate invoca direct pe `Array` pentru că și `Array`, de fapt este o funcție. Cu rol de contructor, dar o funcție fără niciun dubiu, având acces la `apply()`. Pentru aceasta, contextul va fi obiectul global (în cazul browserului este `window`) sau la `null`. Drept argumente, va fi invocat `apply()` pasându-i-se numărul de elemente dorit:
308308

@@ -340,7 +340,7 @@ Array(3).fill(4); // [4, 4, 4]
340340
// {'0':'01', '1':'01', length: 2, ceva: 1}
341341
```
342342

343-
Ultimul caz din seria de exemple de mai sus, se poate dovedi foarte util în practică. Să presupunem că dorești să generezi un obiect prepopulat cu valori din diferite motive. Acest obiect va avea la bază, între oricare alți membri, o pereche cheie:valoare, care va fi folosit drept indicator al dimensiunii array-ului. Ceea ce se va petrece este că aplicarea lui `fill`, care este aplicat obiectului sămânță în care găsește valoarea dimensiunii viitorului array, va conduce la „umplerea” obiectului cu tot atâția noi membri câți au fost specificați de `length`. Singura limitare este că identificatorii cheilor vor fi indecșii. Valorile care vor popula cheile obiectului, pot fi expresii sau valori simple. Am optat mai sus pentru
343+
Ultimul caz din seria de exemple de mai sus, se poate dovedi foarte util în practică. Să presupunem că dorești să generezi un obiect prepopulat cu valori din diferite motive. Acest obiect va avea la bază, între oricare alți membri, o pereche cheie:valoare, care va fi folosit drept indicator al dimensiunii array-ului. Ceea ce se va petrece este că aplicarea lui `fill`, care este aplicat obiectului sămânță în care găsește valoarea dimensiunii viitorului array, va conduce la „umplerea” obiectului cu tot atâția noi membri câți au fost specificați de `length`. Singura limitare este că identificatorii cheilor vor fi indecșii. Valorile care vor popula cheile obiectului, pot fi expresii sau valori simple.
344344

345345
### Crearea unui array multidimensional
346346

@@ -388,7 +388,7 @@ console.log(alta);
388388

389389
Dacă un array are obiecte drept elemente în cazul în care am dori să facem o copie a acelui array, de fapt am face o copie la referințele către obiecte. În limba engleză vom întâlni această situație cu denumirea *shallow copy* - **copie subțire**.
390390

391-
## Manipularea dimensiunii unui array
391+
## Manipularea dimensiunii
392392

393393
### Folosirea proprietății `length`
394394

@@ -413,14 +413,15 @@ function numaraElementeReale (date) {
413413
numaraElementeReale(tablou); // 3
414414
```
415415

416-
### Creșterea lungimii array-ului prin introducerea valorii
416+
### Creșterea lungimii array-ului
417417

418418
```javascript
419419
const tablou = ['x', 'y'];
420420
tablou.length = 3;
421-
// în acest moment ceea ce s-a întâmplat este că a fost introdus un slot gol în array.
422421
```
423422

423+
În acest moment ceea ce s-a întâmplat este că a fost introdus un slot gol în array.
424+
424425
### Scăderea dimensiunii unui array menționând `length`
425426

426427
Se poate face simplu prin:
@@ -435,7 +436,7 @@ console.log(tablou); // Array [ "unu", "doi" ]
435436

436437
### Curățarea unui array cu resetarea sa la zero.
437438

438-
Versatilitatea lui `length` merge mai departe oferind posibilitatea de a reseta la 0 un array.
439+
Versatilitatea lui `length` merge mai departe oferind posibilitatea de a reseta la `0` un array.
439440

440441
```javascript
441442
var tablou = ['unu', 'doi', 'trei', 'patru'];
@@ -446,8 +447,8 @@ console.log(tablou); // Array [ ]
446447
tablou = [];
447448
```
448449

449-
Resetarea array-urilor la 0 - cele referențiate de altele. Există o variantă distructivă și una nedistructivă.
450-
Resetarea la 0 a array-urilor dacă se face cu `length` va avea același efect și pentru toate referințele la acel array. Cine va accesa o referință, va descoperi uimit că este 0.
450+
Resetarea array-urilor la `0` - cele referențiate de altele. Există o variantă distructivă și una nedistructivă.
451+
Resetarea la `0` a array-urilor dacă se face cu `length` va avea același efect și pentru toate referințele la acel array. Cine va accesa o referință, va descoperi uimit că este `0`.
451452

452453
```javascript
453454
var tablou = ['prima', 'a doua'];
@@ -467,7 +468,7 @@ tablou; // []
467468
altTablou; // Array [ "prima", "a doua", 1, 2 ]
468469
```
469470

470-
## Operațiuni cu datele din array
471+
## Operațiuni cu datele
471472

472473
Dacă privești la gradul de populare, unele array-uri pot fi socotite **sparse** (în limba română: *cu goluri*), iar altele fără goluri catalogate a fi **dense**.
473474

obiecte/obiecte-interne-standard/Array/metode-array/Array.from.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,7 @@ function colectDivs(){
5555
var divuri = [...document.querySelectorAll('div')];
5656
```
5757

58-
## Nu poți aplica `slice` pe array-ul rezultat
59-
60-
Cu `Array.from()` nu se poate face `slice()`, dar poți să indici ce sunt părțile.
58+
Nu poți aplica `slice` pe array-ul rezultat. Cu `Array.from()` nu se poate face `slice()`, dar poți să indici ce sunt părțile.
6159

6260
```javascript
6361
function ceEste(){

obiecte/obiecte-interne-standard/Function/introducere-function.md

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,7 @@ Obiectul pasat ca și context de execuție este menționat între paranteze, fii
7777

7878
##### Mecanism de operare a funcțiilor interne ale limbajului
7979

80-
Ține minte că și funcțiile interne (metode ale obiectelor interne), se pot bucura de avantajele folosirii lui `apply()`.
81-
82-
**În cazul obiectului intern Math**
80+
Ține minte că și funcțiile interne (metode ale obiectelor interne), se pot bucura de avantajele folosirii lui `apply()`. În cazul obiectului intern Math:
8381

8482
```javascript
8583
var numere = [12, 43, 32, 3];
@@ -88,9 +86,7 @@ var max = Math.max.apply(null, numere); // 43
8886
var min = Math.min.apply(null, numere); // 3
8987
```
9088

91-
**În cazul obiectului intern Array**
92-
93-
Putem crea un array „dens” (adică populat cu valori):
89+
În cazul obiectului intern `Array` putem crea un array *dens* (adică populat cu valori):
9490

9591
```javascript
9692
Array.apply(null, Array(5)); // Array [ undefined, undefined, undefined, undefined, undefined ]
@@ -140,9 +136,7 @@ Un alt exemplu elocvent este întâlnit la gestionarea evenimentelor atunci cân
140136

141137
### Function.prototype.call()
142138

143-
Apelează o funcție în contextul unui obiect precizat între parantezele rotunde , permițând și pasarea argumentelor funcției. Setează `this` la obiectul pasat și argumentele pot fi pasate așa cum sunt.
144-
145-
Argumentele de după specificarea lui `this` sunt pasate funcției apelată cu call.
139+
Apelează o funcție în contextul unui obiect precizat între parantezele rotunde, permițând și pasarea argumentelor funcției. Setează `this` la obiectul pasat și argumentele pot fi pasate așa cum sunt. Argumentele de după specificarea lui `this` sunt pasate funcției apelată cu `call()`.
146140

147141
```javascript
148142
function faCeva (arg){
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Generator
2+
3+
Este un obiect intern pe care o funcție generator îl generează la momentul execuției. Obiectul implementează protocoalele `iterable` și `iterator`.
4+
5+
```javascript
6+
function* gen () {
7+
yield 'ceva';
8+
yield 'altceva';
9+
};
10+
var obiectG = gen();
11+
// un obiect tip Iterator
12+
```

0 commit comments

Comments
 (0)