ES9 - Nuove funzionalità

Qui apprenderemo le nuove funzionalità di ES9. Cominciamo con la comprensione dei generatori asincroni.

Generatori asincroni e iterazione

I generatori asincroni possono essere resi asincroni utilizzando il asyncparola chiave. Ilsyntax per definire un generatore asincrono è dato di seguito -

async function* generator_name() {
   //statements
}

Esempio

L'esempio seguente mostra un generatore asincrono che restituisce Promise a ogni chiamata a next() metodo di generatore.

<script>
   async function* load(){
      yield await Promise.resolve(1);
      yield await Promise.resolve(2);
      yield await Promise.resolve(3);
   }
   
   let l = load();
   l.next().then(r=>console.log(r))
   l.next().then(r=>console.log(r))
   l.next().then(r=>console.log(r))
   l.next().then(r=>console.log(r))
</script>

L'output del codice precedente sarà il seguente:

{value: 1, done: false}
{value: 2, done: false}
{value: 3, done: false}
{value: undefined, done: true}

per attendere il ciclo

Gli iterabili asincroni non possono essere iterati utilizzando il tradizionale for..of loopsintassi mentre restituiscono le promesse. ES9 introduce ilfor await of loop supportare asynchronous iteration.

La sintassi per l'utilizzo di for await of loop è dato di seguito, dove,

  • Ad ogni iterazione viene assegnato un valore di una proprietà diversa variable e una variabile può essere dichiarata con const, let o var.

  • iterable - Oggetto le cui proprietà iterabili devono essere iterate.
for await (variable of iterable) {
   statement
}

Esempio

L'esempio seguente mostra l'uso di for await of loop per iterare un generatore asincrono.

<script>
   async function* load(){
      yield await Promise.resolve(1);
      yield await Promise.resolve(2);
      yield await Promise.resolve(3);
   }

   async function test(){
      for await (const val of load()){
         console.log(val)
      }
   }
   test();
   console.log('end of script')
</script>

L'output del codice sopra sarà come mostrato di seguito -

end of script
1
2
3

Esempio

L'esempio seguente itera un array utilizzando il ciclo for await of.

<script>
   async function fntest(){
      for await (const val of [10,20,30,40]){
         console.log(val)
      }
   }
   fntest();
   console.log('end of script')
</script>

L'output del codice precedente sarà il seguente:

end of script
10
20
30
40

Proprietà di riposo / diffusione

ES9 supporta l'uso degli operatori Rest e Spread con gli oggetti.

Esempio: Object and Rest Operator

L'esempio seguente mostra l'uso dell'operatore rest con un oggetto. Il valore della proprietà age di student viene copiato nella variabile age mentre i valori delle restanti proprietà vengono copiati nell'altra variabile utilizzando la sintassi del resto `...`.

<script>
   const student = {
      age:10,
      height:5,
      weight:50
   }
   const {age,...other} = student;
   console.log(age)
   console.log(other)
</script>

L'output del codice sopra sarà come indicato di seguito:

10
{height: 5, weight: 50}

Esempio: operatore Object e Spread

L'operatore di diffusione può essere utilizzato per combinare più oggetti o clonare oggetti. Questo è mostrato nel seguente esempio:

<script>
   //spread operator
   const obj1 = {a:10,b:20}
   const obj2={c:30}
   //clone obj1
   const clone_obj={...obj1}
   //combine obj1 and obj2
   const obj3 = {...obj1,...obj2}
   console.log(clone_obj)
   console.log(obj3)
</script>

L'output del codice precedente sarà come indicato di seguito:

{a: 10, b: 20}
{a: 10, b: 20, c: 30}

Promessa: finalmente ()

Il finally()viene eseguito ogni volta che una promessa viene saldata, indipendentemente dal suo esito. Questa funzione restituisce una promessa. Può essere utilizzato per evitare la duplicazione del codice in entrambe le promessethen() e catch() gestori.

Sintassi

La sintassi indicata di seguito è per la funzione finally().

promise.finally(function() {
});
promise.finally(()=> {
});

Esempio

L'esempio seguente dichiara una funzione asincrona che restituisce il quadrato di un numero positivo dopo un ritardo di 3 secondi. La funzione genera un errore se viene passato un numero negativo. In entrambi i casi, le istruzioni nel blocco finalmente vengono eseguite, indipendentemente dal fatto che la promessa venga rifiutata o risolta.

<script>
   let asyncSquareFn = function(n1){
      return new Promise((resolve,reject)=>{
         setTimeout(()=>{
            if(n1>=0){
               resolve(n1*n1)
            }
            else reject('NOT_POSITIVE_NO')
         },3000)
      })
   }
   console.log('Start')

   asyncSquareFn(10)//modify to add -10
   .then(result=>{
      console.log("result is",result)
   }).catch(error=>console.log(error))
   .finally(() =>{
      console.log("inside finally")
      console.log("executes all the time")
   })

   console.log("End");
</script>

L'output del codice precedente sarà come mostrato di seguito

Start
End
//after 3 seconds
result is 100
inside finally
executes all the time

Revisione letterale del modello

A partire da ES7, i modelli con tag sono conformi alle regole delle seguenti sequenze di escape:

  • Le sequenze di escape Unicode vengono rappresentate utilizzando "\u", per esempio \u2764\uFE0F

  • Le sequenze di escape del punto di codice Unicode vengono rappresentate utilizzando "\u{}", per esempio \u{2F}

  • Le sequenze di escape esadecimali sono rappresentate utilizzando "\x", per esempio \xA8

  • Le sequenze di escape letterali ottali sono rappresentate utilizzando "" e seguite da una o più cifre, ad esempio \125

In ES2016 e versioni precedenti, se vengono utilizzate sequenze di escape non valide con funzioni contrassegnate, verrà generato un errore di sintassi come mostrato di seguito:

//tagged function with an invalid unicode sequence
myTagFn`\unicode1`
// SyntaxError: malformed Unicode character escape sequence

Tuttavia, a differenza delle versioni precedenti, ES9 analizza la sequenza Unicode non valida in undefined e non genera un errore. Questo è mostrato nel seguente esempio:

<script>
   function myTagFn(str) {
      return { "parsed": str[0] }
   }
   let result1 =myTagFn`\unicode1` //invalid unicode character
   console.log(result1)
   let result2 =myTagFn`\u2764\uFE0F`//valid unicode
   console.log(result2)
</script>

L'output del codice sopra sarà come mostrato di seguito -

{parsed: undefined}
{parsed: "❤️"}

Corde grezze

ES9 introduce una proprietà speciale raw, disponibile sul primo argomento della funzione tag. Questa proprietà consente di accedere alle stringhe grezze così come sono state immesse, senza elaborare le sequenze di escape.

Esempio

<script>
   function myTagFn(str) {
      return { "Parsed": str[0], "Raw": str.raw[0] }
   }
   let result1 =myTagFn`\unicode`
   console.log(result1)

   let result2 =myTagFn`\u2764\uFE0F`
   console.log(result2)
</script>

L'output del codice precedente sarà il seguente:

{Parsed: undefined, Raw: "\unicode"}
{Parsed: "❤️", Raw: "\u2764\uFE0F"}

Funzionalità di espressione regolare

Nelle espressioni regolari, l'operatore punto o un punto viene utilizzato per trovare la corrispondenza con un singolo carattere. Il. dot operator salta i caratteri di interruzione di riga come \n, \r come mostrato nell'esempio seguente -

console.log(/Tutorials.Point/.test('Tutorials_Point')); //true
console.log(/Tutorials.Point/.test('Tutorials\nPoint')); //false
console.log(/Tutorials.Point/.test('Tutorials\rPoint')); //false

Un modello di espressione regolare è rappresentato come / regular_expression /.Il metodo test () accetta un parametro stringa e cerca il pattern regex. Nell'esempio sopra, iltest() methodcerca pattern che iniziano con Tutorial, seguito da un singolo carattere e finiscono con Point. Se usiamo il\n o \r nella stringa di input tra Tutorial e Point il metodo test () restituirà false.

true
false
false

ES9 introduce una nuova bandiera - DotAllFlag (\s)che può essere utilizzato con Regex per abbinare terminatori di riga ed emoji. Questo è mostrato nel seguente esempio:

console.log(/Tutorials.Point/s.test('Tutorials\nPoint'));
console.log(/Tutorials.Point/s.test('Tutorials\rPoint'));

L'output del codice sopra sarà come indicato di seguito -

true
true

Gruppi di acquisizione con nome

Prima di ES9, l'accesso ai gruppi di acquisizione veniva effettuato dagli indici. ES9 ci consente di assegnare nomi per acquisire gruppi. La sintassi per lo stesso è data di seguito:

(?<Name1>pattern1)

Esempio

const birthDatePattern = /(?<myYear>[0-9]{4})-(?<myMonth>[0-9]{2})/;
const birthDate = birthDatePattern.exec('1999-04');
console.log(birthDate.groups.myYear);
console.log(birthDate.groups.myMonth);

L'output del codice precedente è come mostrato di seguito:

1999
04