Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
1
resposta

[Projeto] Desafio: criando um quiz

const readline = require('readline');

const lr = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

console.log('Boas vindas ao Quiz de JavaScript!');
console.log('Responda com a letra correta: a, b, ou c\n');

let acertos = 0;

lr.question('1) Qual palavras usamos para criar uma função?\n(a) define\n(b) function\n(c) create\n> ', (resposta1) => {
    if (resposta1 == 'b') {
        
        acertos++;
    }

    lr.question('2) Qual dessas é uma estrutura de repetição?\n(a) loopar()\n(b) repeat\n(c) for\n> ', (resposta2) => {
        if (resposta2 == 'c') {
            
            acertos++;
        }

        lr.question('3) Qual valor é considerado falsy em JavaScript?\n(a) 1\n(b) 0\n(c) "texto"\n> ', (resposta3) => {
            if (resposta3 == 'b') {
                
                acertos++;
            }


            if (acertos == 3) {
                console.log('Parabéns, você acertou tudo!!!');
            } else if (acertos == 2) {
                console.log('Muito bom, continue assim!!');
            } else if (acertos == 1) {
                console.log('Bom, Continue estudando!');
            } else {
                console.log('Tente novamente... Continue praticando.');
            }

            lr.close();
        })
    })
})
1 resposta
solução!

Olá, Estudante. Como vai?

Parabéns por concluir o desafio! Desenvolver um quiz interativo via console usando o módulo readline do Node.js é uma excelente maneira de praticar a manipulação de fluxos de entrada e saída de dados, além de consolidar o uso de estruturas condicionais e funções de callback.

O seu código funciona muito bem para a proposta do exercício. No entanto, você deve ter reparado que, à medida que adicionamos mais perguntas, o código começa a ficar muito "esticado" para a direita devido ao aninhamento de funções (lr.question dentro de lr.question). Na programação, conhecemos esse fenômeno como Callback Hell (Inferno de Callbacks) ou Pyramid of Doom (Pirâmide do Destino).

Para agregar ainda mais valor ao seu projeto e transformar esse script em algo muito mais profissional, escalável e elegante, quero compartilhar uma sugestão de como reestruturar seu código utilizando Promises e a sintaxe moderna Async/Await:

Refatorando com Async/Await e laço de repetição

Em vez de aninhar as perguntas manualmente, podemos criar uma única função utilitária que retorna uma Promise. Isso nos permite "esperar" pela resposta do usuário de forma linear. Além disso, podemos isolar as perguntas em um array de objetos, facilitando a adição de novas questões no futuro sem precisar mexer na lógica principal do programa.

Veja como o seu código pode evoluir:

const readline = require('readline');

const lr = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// Função utilitária para transformar o lr.question em uma Promise
const fazerPergunta = (texto) => {
    return new Promise((resolve) => lr.question(texto, resolve));
};

// Banco de dados do quiz isolado em uma estrutura de Array
const perguntas = [
    {
        enunciado: '1) Qual palavra usamos para criar uma função?\n(a) define\n(b) function\n(c) create\n> ',
        respostaCorreta: 'b'
    },
    {
        enunciado: '2) Qual dessas é uma estrutura de repetição?\n(a) loopar()\n(b) repeat\n(c) for\n> ',
        respostaCorreta: 'c'
    },
    {
        enunciado: '3) Qual valor é considerado falsy em JavaScript?\n(a) 1\n(b) 0\n(c) "texto"\n> ',
        respostaCorreta: 'b'
    }
];

// Função principal assíncrona que gerencia o fluxo de forma linear
async function iniciarQuiz() {
    console.log('Boas vindas ao Quiz de JavaScript!');
    console.log('Responda com a letra correta: a, b, ou c\n');

    let acertos = 0;

    // Um único laço percorre todas as perguntas, não importa a quantidade
    for (const pergunta of perguntas) {
        const respostaDoUsuario = await fazerPergunta(pergunta.enunciado);
        
        if (respostaDoUsuario.trim().toLowerCase() === pergunta.respostaCorreta) {
            acertos++;
        }
    }

    // Exibição dos resultados finais
    if (acertos === perguntas.length) {
        console.log('Parabéns, você acertou tudo!!!');
    } else if (acertos >= 2) {
        console.log('Muito bom, continue assim!!');
    } else if (acertos === 1) {
        console.log('Bom, continue estudando!');
    } else {
        console.log('Tente novamente... Continue praticando.');
    }

    lr.close();
}

iniciarQuiz();

O que melhorou nessa abordagem?

  • Legibilidade: O fluxo de execução agora é lido de cima para baixo de forma linear, graças ao await fazerPergunta(), eliminando totalmente as escadinhas de código.
  • Manutenibilidade: Se amanhã você quiser transformar seu quiz em um jogo com 20 perguntas, você só precisa adicionar novos objetos dentro do array perguntas. A lógica da função iniciarQuiz permanecerá exatamente a mesma.
  • Robustez: Adicionamos o .trim().toLowerCase() ao validar a resposta, o que evita que o programa dê erro caso o usuário digite a letra em maiúsculo ou aperte a barra de espaço sem querer.

Você teve uma excelente iniciativa ao aplicar esses conceitos criando um quiz real. Continue explorando as capacidades do JavaScript!

Espero que possa ter lhe ajudado!