Node.js Generators e comparar com retornos de chamada

Neste tutorial, vamos aprender sobre Generatorse suas diferenรงas com retornos de chamada

O que sรฃo geradores?

Generatorse tornaram bastante famosos em Node.js nos รบltimos tempos e isso provavelmente se deve ao que sรฃo capazes de fazer.

  • Generators sรฃo execuรงรตes de funรงรตes que podem ser suspensas e retomadas posteriormente.
  • Generators sรฃo รบteis ao executar conceitos como 'execuรงรฃo lenta'. Basicamente, isso significa que, ao suspender a execuรงรฃo e retomar ร  vontade, podemos extrair valores apenas quando necessรกrio.

Generators tรชm os 2 mรฉtodos principais abaixo.

  1. Mรฉtodo de rendimento โ€“ O mรฉtodo yield รฉ chamado em uma funรงรฃo para interromper a execuรงรฃo da funรงรฃo na linha especรญfica onde o mรฉtodo yield รฉ chamado.
  2. Prรณximo mรฉtodo โ€“ Este mรฉtodo รฉ chamado a partir da aplicaรงรฃo principal para retomar a execuรงรฃo de uma funรงรฃo que possui um mรฉtodo yield. A execuรงรฃo da funรงรฃo continuarรก atรฉ o prรณximo mรฉtodo de rendimento ou atรฉ o final do mรฉtodo.

Vejamos um exemplo de como os geradores podem ser usados.

Em nosso exemplo, teremos uma funรงรฃo Add simples que adicionarรก 2 nรบmeros, mas continuaremos interrompendo a execuรงรฃo do mรฉtodo em diferentes pontos para mostrar como os geradores podem ser usados.

Node.js Generators

function* Add(x) {
   yield x + 1;
   var y = yield(null);
   y = 6
   return x + y;
}

var gen = Add(5);

gen.next();

gen.next(); 

Code Explicaรงรฃo

  1. O primeiro passo รฉ definir a โ€œfunรงรฃoโ€ do nosso gerador. Observe que isso รฉ feito adicionando um โ€œ*โ€ ร  palavra-chave da funรงรฃo. Estamos entรฃo definindo uma funรงรฃo chamada Add que recebe um parรขmetro de x.
  2. A palavra-chave yield รฉ especรญfica para geradores. Isso o torna uma construรงรฃo poderosa para pausar uma funรงรฃo no meio de qualquer coisa. Entรฃo aqui, a execuรงรฃo da funรงรฃo serรก interrompida atรฉ invocarmos a funรงรฃo next(), o que serรก feito na Etapa 4. Neste ponto, o valor de x passarรก a ser 6 e a execuรงรฃo da funรงรฃo serรก interrompida.
  3. ร‰ aqui que primeiro chamamos a funรงรฃo geradora e enviamos o valor 5 para nossa funรงรฃo Add. Este valor serรก substituรญdo no parรขmetro x da nossa funรงรฃo Adicionar.
  4. Assim que chamarmos a funรงรฃo next(), a funรงรฃo Add() retomarรก a execuรงรฃo. Quando a prรณxima instruรงรฃo var y= yield(null) for executada, a funรงรฃo Add() irรก parar de executar novamente.
  5. Agora, depois de chamar a funรงรฃo next() novamente, as prรณximas instruรงรตes serรฃo executadas e o valor combinado de x=5 e y=6 serรก adicionado e retornado.

Retornos de chamada vs. geradores

Generators sรฃo usados โ€‹โ€‹para resolver o problema conhecido como callback hell. ร€s vezes, as funรงรตes de retorno de chamada ficam tรฃo aninhadas durante o desenvolvimento de um aplicativo Node.js que fica muito complicado usar funรงรตes de retorno de chamada.

ร‰ aqui que os geradores sรฃo รบteis. Um dos exemplos mais comuns disso รฉ ao criar funรงรตes de timer.

Vejamos o exemplo abaixo de como os geradores podem ser รบteis em retornos de chamada.

Nosso exemplo criarรก apenas uma funรงรฃo simples de atraso de tempo. Gostarรญamos entรฃo de chamar esta funรงรฃo incorporando um atraso de 1000, 2000 e 3000 ms.

Passo 1) Defina nossa funรงรฃo de retorno de chamada com o cรณdigo de atraso necessรกrio.

Retornos de chamada vs. Generators

function Timedelay(ptime, callback) {

setTimeout(function() {
  
    callback("Pausing for " + ptime);
    
  }, time);
}

Code Explicaรงรฃo

  1. Aqui estamos criando uma funรงรฃo chamada Timedelay com um parรขmetro chamado ptime. Isso levarรก o atraso necessรกrio que queremos introduzir em nosso aplicativo.
  2. O prรณximo passo รฉ apenas criar uma mensagem, que serรก exibida ao usuรกrio informando que a aplicaรงรฃo ficarรก pausada por vรกrios milissegundos.

Passo 2) Agora vamos dar uma olhada no cรณdigo se estivรฉssemos incorporando retornos de chamada. Suponha que quisรฉssemos incorporar retornos de chamada com base no valor de 1000, 2000 e 3000 milissegundos. O cรณdigo abaixo mostra como precisarรญamos implementรก-los usando retornos de chamada.

Retornos de chamada vs. Generators

Timedelay(1000, function(message) {
  
  console.log(msg);
  Timedelay(2000, function(message) {
    
    console.log(msg);
    Timedelay(3000, function(message) {
      
      console.log(msg);
  })
  })
})

Code Explicaรงรฃo

  1. Estamos chamando Timedelay como um retorno de chamada com 1000 como valor.
  2. Em seguida, queremos chamar a funรงรฃo Timedelay novamente com 2000 como valor.
  3. Finalmente, queremos chamar a funรงรฃo Timedelay novamente com 3000 como valor.

No cรณdigo acima, vocรช pode ver que fica mais confuso, pois queremos comeรงar a chamar a funรงรฃo vรกrias vezes.

Passo 3) Agora vamos ver como implementar o mesmo cรณdigo usando geradores. No cรณdigo abaixo vocรช pode ver como se tornou simples implementar a funรงรฃo Timedelay usando geradores.

Retornos de chamada vs. Generators

function* Messages() {
  console,log(yield(Timedelay(1000, function(){})));
  console,log(yield(Timedelay(2000, function(){})));
  console,log(yield(Timedelay(3000, function(){})));
}

Code Explicaรงรฃo

  1. Estamos primeiro definindo uma funรงรฃo geradora que serรก usada para chamar nossa funรงรฃo Timedelay.
  2. Estamos chamando a funรงรฃo Yield junto com a funรงรฃo Timedelay com 1000 como valor do parรขmetro.
  3. Em seguida, chamaremos a funรงรฃo Yield junto com a funรงรฃo Timedelay com 2000 como valor do parรขmetro.
  4. Finalmente, estamos chamando a funรงรฃo Yield junto com a funรงรฃo Timedelay com 3000 como valor do parรขmetro.

Resumo

Generators tambรฉm pode ser usado para aliviar os problemas com retornos de chamada aninhados e ajudar a remover o que รฉ conhecido como inferno de retorno de chamada. Generators sรฃo usados โ€‹โ€‹para interromper o processamento de uma funรงรฃo. Isso รฉ conseguido usando o mรฉtodo 'yield' na funรงรฃo assรญncrona.

Resuma esta postagem com: