ES9 - Novos recursos

Aqui, aprenderemos sobre os novos recursos do ES9. Vamos começar entendendo sobre os geradores assíncronos.

Geradores assíncronos e iteração

Geradores assíncronos podem se tornar assíncronos usando o asyncpalavra-chave. osyntax para definir um gerador assíncrono é fornecido abaixo -

async function* generator_name() {
   //statements
}

Exemplo

O exemplo a seguir mostra um gerador assíncrono que retorna Promise em cada chamada para o next() método do gerador.

<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>

A saída do código acima será a seguinte -

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

para aguardar o loop

Os iteráveis ​​assíncronos não podem ser iterados usando o tradicional for..of loopsintaxe como eles retornam promessas. ES9 apresenta ofor await of loop suportar asynchronous iteration.

A sintaxe para usar o for await of loop é dado abaixo, onde,

  • Em cada iteração, um valor de uma propriedade diferente é atribuído a variable e uma variável pode ser declarada com const, let ou var.

  • iterable - Objeto cujas propriedades iteráveis ​​devem ser iteradas.
for await (variable of iterable) {
   statement
}

Exemplo

O exemplo a seguir mostra o uso de for await of loop para iterar um gerador assíncrono.

<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>

A saída do código acima será conforme mostrado abaixo -

end of script
1
2
3

Exemplo

O exemplo a seguir itera uma matriz usando o loop 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>

A saída do código acima será a seguinte -

end of script
10
20
30
40

Propriedades de repouso / propagação

ES9 suporta o uso de operadores Rest e Spread com objetos.

Exemplo: Operador de objeto e repouso

O exemplo a seguir mostra o uso do operador rest com um objeto. O valor da propriedade age do aluno é copiado para a variável age enquanto os valores das propriedades restantes são copiados para a outra variável usando a sintaxe rest `...`.

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

A saída do código acima será conforme fornecido abaixo -

10
{height: 5, weight: 50}

Exemplo: operador Object e Spread

O operador de propagação pode ser usado para combinar vários objetos ou objetos de clonagem. Isso é mostrado no seguinte exemplo -

<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>

A saída do código acima será conforme indicado abaixo -

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

Promessa: finalmente ()

o finally()é executada sempre que uma promessa é cumprida, independentemente do seu resultado. Esta função retorna uma promessa. Pode ser usado para evitar a duplicação de código em ambas as promessasthen() e catch() manipuladores.

Sintaxe

A sintaxe abaixo mencionada é para a função finally().

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

Exemplo

O exemplo a seguir declara uma função assíncrona que retorna o quadrado de um número positivo após um atraso de 3 segundos. A função gera um erro se um número negativo for passado. As instruções no bloco finally são executadas em qualquer caso, seja a promessa rejeitada ou resolvida.

<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>

A saída do código acima será como mostrado abaixo

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

Revisão literal do modelo

A partir do ES7, os modelos marcados estão em conformidade com as regras das seguintes sequências de escape -

  • As sequências de escape Unicode são representadas usando "\u", por exemplo \u2764\uFE0F

  • As sequências de escape do ponto de código Unicode são representadas usando "\u{}", por exemplo \u{2F}

  • As sequências de escape hexadecimais são representadas usando "\x", por exemplo \xA8

  • As sequências de escape literal octal são representadas usando "" e seguidas por um ou mais dígitos, por exemplo \125

No ES2016 e anteriores, se sequências de escape inválidas forem usadas com funções marcadas, um erro de sintaxe será lançado conforme mostrado abaixo -

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

No entanto, ao contrário das versões anteriores, o ES9 analisa a sequência unicode inválida para indefinida e não lança um erro. Isso é mostrado no seguinte exemplo -

<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>

A saída do código acima será conforme mostrado abaixo -

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

Strings Raw

ES9 apresenta uma propriedade especial raw, disponível no primeiro argumento para a função de tag. Esta propriedade permite acessar as strings brutas conforme foram inseridas, sem processar as sequências de escape.

Exemplo

<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>

A saída do código acima será a seguinte -

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

Recurso de expressão regular

Em expressões regulares, o operador ponto ou ponto é usado para corresponder a um único caractere. o. dot operator pula caracteres de quebra de linha como \n, \r conforme mostrado no exemplo abaixo -

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

Um padrão de expressão regular é representado como / regular_expression /.O método test () usa um parâmetro de string e procura o padrão regex. No exemplo acima, otest() methodprocura um padrão começando com Tutoriais, seguido por qualquer caractere único e terminando com Ponto. Se usarmos o\n ou \r na string de entrada entre Tutorials e Point, o método test () retornará false.

true
false
false

ES9 apresenta uma nova bandeira - DotAllFlag (\s)que pode ser usado com Regex para combinar terminadores de linha e emojis. Isso é mostrado no seguinte exemplo -

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

A saída do código acima será conforme mencionado abaixo -

true
true

Grupos de captura nomeados

Antes do ES9, os grupos de captura eram acessados ​​por índices. ES9 nos permite atribuir nomes a grupos de captura. A sintaxe para o mesmo é fornecida abaixo -

(?<Name1>pattern1)

Exemplo

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);

A saída do código acima é mostrada abaixo -

1999
04