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