# Aula 14 - Node ## Porque usamos Node.js A principal utilidade de node é utilizar todo conhecimento que temos com Javascript para a Web e conseguir aplicar ele para executar outras atividades que fogem de atividade padrão que é dar vida à paginas web. De uma maneira simples, podemos hoje fazer tudo com Node.js, fazer programas para tratar dados, fazer aplicativos, programas para interagir com banco de dados. Trabalhar com inteligência artificial, tantos e tantos domínios que podemos aplicar utilizando Node.js. Graças ao Node.js, hoje tem-se uma infinidade de caminhos a se seguir utilizando a mesma linguagem. Você não mais precisa aprender um novo domínio, se você quiser fazer `apenas algo bem o suficiente`. Apesar disso, Node.js e Javascript não é uma bala de prata, ela não deve ser mal interpretada e considerada `a melhor solução` para tudo. ## Módulos Lembra nos exercícios de lógica em que usamos a `Math.pow`? Ela calculava a potência de um número, e ela era usada assim: ```javascript= Math.pow(7, 2); // Resultado: 49; ``` A função `pow` é uma função do módulo `Math`, e pra gente, ela está sempre disponível quando quisermos utilizar algumas funções matemáticas. Mas o que são módulo? **```Módulos nada mais são do que códigos com funções ou variáveis já prontas para usarmos.```** Existem outros módulos que não estão disponíveis sempre e precisamos nominalmente chamá-los em nosso código em `node`. Para isso, usamos a seguinte sintaxe: ```javascript const nomeDoModulo = require('nome_do_modulo'); ``` Um exemplo disso é o módulo do `node` que utilizamos para gerir arquivos, o módulo `fs`, ele é usado da seguinte maneira: ```javascript= const fs = require('fs'); fs.open('meu_novo_arquivo.txt', 'w', function (err, file) { console.log('Novo arquivo salvo!'); }); ``` De uma maneira prática, esse código cria um novo arquivo caso ele não consiga encontrar um arquivo em branco com o nome `meu_novo_arquivo.txt`. Conseguimos entender algumas coisas desse código. Na primeira linha, temos a definição de uma constante, e como vimos ali, essa sintaxe significa a utilização de algum módulo (ou seja, algum trecho de código que vai nos ajudar a fazer alguma ação, como o `Math.pow`, por exemplo). Na terceira linha, temos algumas novas, mas temos coisas que conhecemos. Temos uma sintaxe que parece de um objeto com `fs.open` e temos uma função com `.open(...)`. Uma função de três argumentos, os dois primeiros textos e o último, uma função? Sim, uma função. Podemos passar uma declaração de uma função como argumento de outra função. Interessante, não é? Essa função é destinada a ser executada em um dado momento do código, e essa função tem o nome de `callback`, vamos entender mais um pouquinho mais adiante. E finalmente dentro da função do que chamamos de `callback`, chamamos a função `console.log` para com a mensagem `Novo arquivo salvo!`. Para sanar ainda mais dúvidas, o primeiro argumento é o nome do arquivo que se quer criar ou salvar. O segundo argumento refere-se ao que chamamos de `flag`, podemos apenas querer ler o arquivo, nesse caso, passariamos a flag `r` de `read` (em português, leitura). No exemplo, passamos a flag `w`, de `write` (em português, escrita) com a intenção de escrever, criar novas informações. ## Callbacks Aprendemos na última aula de lógica um pouco sobre funções e vimos como elas se comportam. E veremos também, que tudo em Node.js é melhor aproveitado utilizando funções. Utilizamos na última aula exemplos como `console.log(calcularPotencia(2, 3))`. Esse é um caso que uma função (`calcularPotencia`) está sendo executada e seu resultado está sendo passado para outra função, `console.log` neste caso. Então o que está acontecendo é que: 1. `calcularPotencia(2, 3)` está sendo calculado primeiro; 2. Seu resultado é armazenado; 3. Então ele é passado como argumento para o `console.log` Podemos pensar uma outra forma também de lidar com funções, e se quisessemos chamar funções para serem executadas dentro de outras funções sem se preocupar? Como vimos no exemplo anterior, podemos declarar uma função como argumento de outra função. Vamos ver outro exemplo? Vamos supor que queiramos lidar de maneira interativa com o usuário. Ao rodarmos nosso programa, ele faça perguntas ao usuário e o programa continue rodando enquanto existam perguntas. Para esse caso, poderiamos usar outro módulo, ou seja, outro trecho de código já feito que vai nos permitir interagir com o usuário. Vamos ver: ```javascript= const readline = require("readline"); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); rl.question('Qual é curso você está fazendo?', function qualCurso(resposta) { console.log(resposta); rl.close(); }); ``` Conseguimos entender algumas partes desse código, e a gente não precisa entender tudo para que faça sentido. Na primeira linha, como vimos, estamos avisando que precisamos usar algum módulo, neste caso, o módulo `readline`. E estamos avisando que vamos usar a variável readline como forma de chamá-lo. Da linha 2 até 5, existe alguma função `createInstance` sendo chamada que não entendemos o que ela faz. Na linha 7, existe outra função sendo chamada utilizando a resposta do que foi gerado entre a linha 2 e 5. Essa função tem dois argumentos, o primeiro é um texto que nesse caso parece uma pergunta e o segundo, é uma função que nesse caso, possui um argumento, resposta, e ele é usada imediatamente em um `console.log` na linha 8. Na linha 9, por fim existe outra função sendo chamada, `rl.close()`. Se a gente rodar esse código, o que acontece? ![](https://i.imgur.com/t2tn5bl.png) Ele pergunta o que estava na linha 7 e não termina o programa. Se a gente responder o programa escrevendo algum conteúdo e dando enter. O que acontece? ![](https://i.imgur.com/81aLiAv.png) Ele imprime o que escrevemos e encerra o programa. Bom, isso ajuda bastante. Será que conseguimos mudar isso? E se quisessemos deixar mais complexo? ```javascript= const readline = require("readline"); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); rl.question("Qual é curso você está fazendo?", function qualCurso(resposta) { console.log(resposta); rl.question("Qual seu estado?", function qualEstado(resposta) { console.log(resposta); rl.close(); }); }); ``` Agora encadeamos mais uma função `question` dentro da primeira. O que acontece se rodarmos esse código? ![](https://i.imgur.com/9kXUeSL.png) Ele encadeia as perguntas também. Então a gente pode entender que funções em javascript são como legos, podemos montá-las e usá-las em várias composições, unindo uma por uma. E lembrando: a gente não precisa entender o que é feito pela função `createInterface`, porque entendemos o comportamento do restante. E pouco a pouco vamos entendendo outras partes que antes eram desconhecidas. Hoje, aprendemos sobre módulos e callbacks. Por último, vamos para outra função e se quisessémos escrever dentro conteúdo dentro de um arquivo e não só criá-lo? Vamos usar outra função do módulo `fs`. ```javascript= const fs = require('fs'); fs.writeFile( 'mensagem.txt', 'Este é o curso intensivo da Cubos Academy!', 'utf8', function imprimir() { console.log('Novo conteúdo salvo ao arquivo!'); }); ``` O que acontece se rodarmos esse script? ![](https://i.imgur.com/83t3yE6.png) A mensagem é impressa e um novo arquivo é criado (`mensagem.txt`) com o conteúdo de `Este é o curso intensivo da Cubos Academy!`. O que conseguimos entender desse código? Na linha 1, existe o que chamamos de importação de um módulo; Na linha 2 até 8 existe uma execução de uma função `writeFile` do módulo `fs`; Separados por linha, entre a linha 3 e 6, existem 4 (quatro) argumentos para a função `writeFile`; Os três primeiros argumentos são textos e o último uma função de `callback`. O callback é usado para imprimir uma mensagem. Para sanar as dúvidas, a função `writeFile` é usada para substituir um arquivo e seu conteúdo ou criar um novo com conteúdo. O primeiro argumento é de fato o nome do arquivo a ser substituído ou criado, o segundo argumento refere-se ao dado inserido no arquivo, o terceiro refere-se a como esse arquivo deve ser interpretado (enconding) e aprenderemos isso nas próximas aulas e por último argumento, um callback para efetuar alguma ação quando a escrita do arquivo for finalizada. **Observação**: É importante notar que funções de callback podem ser utilizadas de diversas formas, tanto para executar ações durante a execução da função que a chama, quanto no final, para avisar que a execução terminou.