1
resposta

[JavaScript com Node.js: Criando sua primeira biblioteca] [Módulo: 04 -Import/export e promessas] - Atividade de aula

Oi pessoal, tudo bem? Estou tentando replicar o conteúdo da aula considerando algumas mudanças e ajustes. No entanto estou enfrentando alguns problemas pra conseguir fazer meu código rodar com as promisses e funções assíncronas. Por exemplo:

Um pouco diferente da aula, eu criei a estrutura de arquivos da seguinte forma:

cli.js --> para rodar o cli e as entradas do código erros.js --> para gravar o logo dos erros limpaPequenas --> arquivo que contém a função para limpar os caracteres especiais separadorPalavras --> arquivo que contém a função para separar o texto por palavras separadorParagrafos ->> arquivo que contém a função para separar o texto por parágrafos

Problema: Não estou conseguindo fazer com que a função readfile no cli.js receba o array de objetos que contém a contagem das palavras vindas do arquivo limpaPequenas.js na função elimina pequenas. Com isso, não consigo fazer com o que o código chegue a rodar a função assícrona criarArquivoLog para poder fazer a gravação do arquivo de log com o erro de input que estou tentando forçar no terminal.

//cli.js

import fs from 'fs';
import separaPagrafo from './separadorParagrafo.js';
import tratamentoErros from './erros.js';
import { eliminaPequenas } from './limpaPequenas.js';
import { separaPalavras } from './separadorPalavras.js';


const textoCapturado = process.argv[2]
const textoGravado = process.argv[3]



fs.readFile(textoCapturado, 'utf8', (error, texto) => {
    try{
        if(error) throw error
        const resultadoObj = separaPagrafo(texto)
        
        criarArquivoLog(resultadoObj, textoGravado)
        }
        catch(error){
            tratamentoErros(error)
/*             if (error.code === 'ENOENT') console.log('erro esperado', error.code);
            else console.log ('então é outro erro', error.code)  */

            
        }
    

})




async function criarArquivoLog(resultadoObj, path){
    console.log(resultadoObj)
    const resultadoObjJSON = JSON.stringify(resultadoObj);
    const caminhoArquivo = `${path}/teste.txt`;

//erros.js

export default function tratamentoErros (erro){
    if (erro.code === 'ENOENT'){
        throw new Error('arquivo não encontrado')
    }
    else{ console.log ('então é outro erro')}
}

//limpaPequenas.js

export function eliminaPequenas(palavras){
    const objCount = {};
    
    //console.log(palavras)
    palavras.forEach(palavrasPequenas => {
        const pequenasElimin = palavrasPequenas.replace(/[.,\/#!$%\^?&\*;:{}=\-_`~()]/g, '')
        //console.log(pequenasElimin)
        if(pequenasElimin.length >3){
           objCount[pequenasElimin] = ((objCount[pequenasElimin] || 0) + 1);

        }
    })
    //console.log(objCount)
    return objCount}

//separadorPalavras.js

import { eliminaPequenas } from "./limpaPequenas.js";

export function separaPalavras(texto){
    
    texto.forEach(paragrafo => { 
        eliminaPequenas(paragrafo.toLowerCase().split(' '))     
        

    })

    
  }

//separadorParagrafo.js

import {separaPalavras} from "./separadorPalavras.js";


export default function separaPagrafo(texto){
    
    const splitDeParagrafos = texto.split('\n');
    //console.log(splitDeParagrafos)
    const vetorParagrafo = splitDeParagrafos.map(paragrafo => {
        return paragrafo
   
    //console.log(objCont)
    //separaPalavras(splitDeParagrafos);
})
//console.log(vetorParagrafo)
separaPalavras(vetorParagrafo);

}

Agradeço muito se puderem contribuir para contornar aqui.

Obrigado!

1 resposta

Oi Rafael, tudo bem?

Pelo que entendi, você está tendo dificuldades em passar os resultados de uma função assíncrona (a que processa os arquivos) para outras funções, e também em integrar as promessas corretamente para fazer com que o arquivo de log seja criado no final.

Segue essas etapas:

1. Corrigir o fluxo assíncrono

O primeiro ponto é que você está misturando funções síncronas e assíncronas e, ao fazer isso, não está esperando o resultado da função assíncrona antes de prosseguir com o próximo passo.

Por exemplo, o separaPalavras não está retornando nada, mas deveria retornar os dados para que o eliminaPequenas possa trabalhar com eles. Além disso, o criarArquivoLog precisa ser uma função assíncrona porque você vai fazer uma operação de escrita no disco, que é assíncrona também.

2. Reestruturação das funções para usar async/await

Vamos reestruturar um pouco as funções para que o fluxo assíncrono funcione corretamente e as promessas sejam resolvidas antes de passar os dados adiante.

Passo 1: Corrigir a função separaPalavras

Essa função recebe o texto, divide em parágrafos e passa as palavras para a função eliminaPequenas. Porém, ela não retorna nada, o que impede a passagem dos dados para a próxima função. Vamos ajustá-la para que ela retorne o resultado.

// separadorPalavras.js
import { eliminaPequenas } from "./limpaPequenas.js";

export async function separaPalavras(texto){
    const resultado = [];

    // Agora a função retorna o resultado das palavras
    texto.forEach(paragrafo => { 
        resultado.push(eliminaPequenas(paragrafo.toLowerCase().split(' '))); 
    })

    return resultado; // Retorna o resultado para ser manipulado no próximo passo
}

Passo 2: Corrigir a função separaPagrafo

Agora que separaPalavras retorna um resultado, podemos usar esse resultado para realizar os próximos passos.

// separadorParagrafo.js
import { separaPalavras } from "./separadorPalavras.js";

export default async function separaPagrafo(texto){
    const splitDeParagrafos = texto.split('\n');
    const vetorParagrafo = splitDeParagrafos.map(paragrafo => paragrafo.trim());

    // Aqui, retornamos a função assíncrona e aguardamos o resultado
    return await separaPalavras(vetorParagrafo);
}

Passo 3: Corrigir a função cli.js

Agora que as funções de processamento de texto são assíncronas, vamos corrigir a forma como você lida com as promessas. A função fs.readFile também é assíncrona, então vamos garantir que todo o fluxo seja controlado com async/await.

// cli.js
import fs from 'fs';
import separaPagrafo from './separadorParagrafo.js';
import tratamentoErros from './erros.js';
import { eliminaPequenas } from './limpaPequenas.js';
import { separaPalavras } from './separadorPalavras.js';

const textoCapturado = process.argv[2];
const textoGravado = process.argv[3];

fs.readFile(textoCapturado, 'utf8', async (error, texto) => {
    try {
        if (error) throw error;

        // Agora a função separaPagrafo retorna uma Promise, então usamos await
        const resultadoObj = await separaPagrafo(texto);

        // Chama a função para criar o arquivo de log
        await criarArquivoLog(resultadoObj, textoGravado);
    } catch (error) {
        // Lidar com o erro
        tratamentoErros(error);
    }
});

async function criarArquivoLog(resultadoObj, path) {
    console.log(resultadoObj);

    const resultadoObjJSON = JSON.stringify(resultadoObj);
    const caminhoArquivo = `${path}/teste.txt`;

    // Escrevendo o arquivo de log
    fs.writeFile(caminhoArquivo, resultadoObjJSON, 'utf8', (err) => {
        if (err) throw err;
        console.log('Arquivo de log criado!');
    });
}

3. Entendendo os problemas no fluxo

Agora que reestruturamos o código, o fluxo está claro:

  • O código lê o arquivo de texto com fs.readFile, que é assíncrono.
  • Depois, ele passa o texto para separaPagrafo, que por sua vez chama separaPalavras e eliminaPequenas.
  • Ao final, o resultado é gravado em um arquivo com a função criarArquivoLog.

4. Ajustar a função eliminaPequenas

A função eliminaPequenas estava correta em sua lógica, mas ela agora será chamada em um contexto assíncrono. O que fizemos foi garantir que ela processasse os dados corretamente. Aqui não é necessário alterar nada, mas fica bom ter em mente que ela deve processar as palavras e retornar o objeto.

// limpaPequenas.js
export function eliminaPequenas(palavras){
    const objCount = {};
    
    palavras.forEach(palavra => {
        const pequenasElimin = palavra.replace(/[.,\/#!$%\^?&\*;:{}=\-_`~()]/g, '');
        
        if(pequenasElimin.length > 3){
            objCount[pequenasElimin] = (objCount[pequenasElimin] || 0) + 1;
        }
    })
    
    return objCount;
}

Boa sorte com o projeto!