Node.js — Funções Generators Assíncronas e Websockets

Image for post
Image for post

As funções generator assíncronas são um novo recurso no ES2018. Node.js adicionou suporte para funções generator assíncrona no Node.js 10. As funções generator assíncrona podem parecer um recurso de nicho bonito, mas apresentam uma ótima oportunidade para estruturar websockets em Node.js. Neste artigo, explicarei como uma estrutura de websocket Node.js pode usar funções generator assíncronas.

Classificando frameworks HTTP

Primeiro, pense em frameworks de servidor HTTP, como Express ou Hapi . Em geral, a maioria das estruturas de servidor HTTP se enquadra em uma das 3 classes:

  1. Resposta explícita — Para enviar uma resposta HTTP no Express, você deve chamar res.end(), res.json() ou alguma outra função no objeto res. Em outras palavras, você precisa chamar explicitamente um método para enviar uma resposta.
  2. Resposta implícita usando return - Por outro lado, o Hapi v17 removeu explicitamente a função reply(). Portanto, Hapi não tem um equivalente a res: para enviar uma resposta, você return um valor de seu manipulador de solicitação. Hapi então converte o valor de return em uma resposta HTTP.
  3. Modifique a resposta no localKoa usa uma abordagem distinta que é uma mistura das duas anteriores. Em vez de chamar funções res, você modifica um objeto ctx para estruturar sua resposta.

Em outras palavras, alguns frameworks HTTP fazem com que você chame explicitamente uma função para enviar a resposta HTTP, alguns fornecem um objeto de resposta HTTP para modificar e alguns apenas pegam o valor de return de uma função manipuladora de requisição.

A diferença entre websockets e HTTP é que o servidor pode enviar mensagens para o socket sempre que quiser, seja em resposta a uma mensagem ou não. Isso significa que estruturas de websocket de baixo nível como ws se parecem muito com o padrão de “resposta explícita”: você precisa chamar explicitamente uma função para enviar uma mensagem.

Mas você poderia fazer algo como resposta implícita com websockets, mantendo o benefício de poder enviar várias mensagens? É aí que entram os geradores assíncronos.

Lendo Pedaços de Informação no Servidor

Suponha que você tenha um cursor Mongoose que lê um monte de documentos, um de cada vez, e deseja enviar cada documento por um websocket assim que o cursor o ler. Isso pode ser útil se você quiser minimizar a quantidade de memória que seu servidor usa a qualquer momento: o cliente obtém todos os dados, mas o servidor nunca precisa manter todos os dados em memória de uma só vez. Por exemplo, veja como você pode ler um cursor usando async/await:

O que torna os generators tão interessantes é que yield são como um return, exceto que uma função pode fazer yield várias vezes e continuar de onde parou. Portanto, uma função de gerador assíncrono pode fazer várias respostas implícitas.

Veja como você pode construir um servidor websocket com Node.js :

Portanto, agora, o truque é colar o servidor websocket a função streamUsers(). Suponha que cada mensagem recebida seja um JSON válido e tenha as propriedades actione id. Quando action === 'streamUsers', você pode chamar streamUsers() e enviar todos os usuários para o socket conforme eles saem do cursor Mongoose.

Veja como você chamaria streamUsers() por meio do cliente websocket:

Finalizando

As funções generators assíncronas fornecem uma oportunidade para criar uma estrutura de websocket de nível superior com base no padrão de resposta implícito que as estruturas HTTP como Hapi e Fastify usam. O principal benefício do padrão de resposta implícito é que sua lógica de negócios não precisa estar ciente se o framework está enviando o resultado via websocket, pesquisa de HTTP ou outra coisa. JavaScript sem framework é mais portátil e fácil de testar.

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store