171 votes

Lecture interactive d'une valeur à partir de la console

J'ai pensé à faire un simple serveur http avec une extension de console. J'ai trouvé le snippet pour lire les données de la ligne de commande.

  var i = rl.createInterface(process.stdin, process.stdout, null);
  i.question('Write your name: ', function(answer) {
    console.log('Nice to meet you> ' + answer);
    i.close();
    process.stdin.destroy();

  });

Pour poser les questions de manière répétée, je ne peux pas simplement utiliser la fonction while(done) { } boucle ? De même, si le serveur reçoit une sortie au moment de la question, cela ruine la ligne.

6 votes

Je suppose qu'en rl vous voulez dire ligne de lecture ?

0 votes

Vous pouvez utiliser une interface non bloquante comme celle utilisée dans cette réponse , vous pouvez alors faire un while(done) boucle.

12voto

please delete me Points 206

La réponse @rob fonctionnera la plupart du temps, mais il se peut qu'elle ne fonctionne pas comme vous l'attendiez avec des entrées longues.

C'est ce que vous devriez utiliser à la place :

const stdin = process.openStdin();
let content = '';

stdin.addListener('data', d => {
  content += d.toString();
});

stdin.addListener('end', () => {
  console.info(`Input: ${content}`);
});

Explication de la raison pour laquelle cette solution fonctionne :

addListener('data') fonctionne comme un tampon, le rappel sera appelé lorsqu'il est plein ou/et qu'il s'agit de la fin de l'entrée.

Qu'en est-il des entrées longues ? Une seule 'data' ne suffira pas, vous obtiendrez alors une entrée divisée en deux ou plusieurs parties. Ce n'est souvent pas pratique.

addListener('end') nous informera lorsque le lecteur stdin aura fini de lire notre entrée. Puisque nous avons stocké les données précédentes, nous pouvons maintenant les lire et les traiter ensemble.

3 votes

Lorsque j'utilise le code ci-dessus et que j'insère des données, puis que j'appuie sur la touche "Entrée", la console me demande sans cesse d'entrer d'autres données.

9voto

Miguel Mota Points 14005

Voici un exemple :

const stdin = process.openStdin()

process.stdout.write('Enter name: ')

stdin.addListener('data', text => {
  const name = text.toString().trim()
  console.log('Your name is: ' + name)

  stdin.pause() // stop reading
})

Sortie :

Enter name: bob
Your name is: bob

0 votes

Belle réponse mon frère ! Simple et claire.

5voto

Diogo Cardoso Points 3985

Je recommande d'utiliser Inquirer car il fournit une collection d'interfaces utilisateur interactives courantes en ligne de commande.

const inquirer = require('inquirer');

const questions = [{
  type: 'input',
  name: 'name',
  message: "What's your name?",
}];

const answers = await inquirer.prompt(questions);
console.log(answers);

3voto

C'est trop compliqué. Une version plus simple de :

var rl = require('readline');
rl.createInterface... etc

serait d'utiliser

var rl = require('readline-sync');

il attendra alors que vous utilisiez

rl.question('string');

il est alors plus facile de le répéter. par exemple :

var rl = require('readline-sync');
for(let i=0;i<10;i++) {
    var ans = rl.question('What\'s your favourite food?');
    console.log('I like '+ans+' too!');
}

2voto

zoran404 Points 474

Un cas d'utilisation courant serait probablement que l'application affiche une invite générique et la traite dans une instruction de commutation.

Vous pourriez obtenir un comportement équivalent à celui d'une boucle while en utilisant une fonction d'aide qui s'appellerait elle-même dans le rappel :

const readline = require('readline');
const rl = readline.createInterface(process.stdin, process.stdout);

function promptInput (prompt, handler)
{
    rl.question(prompt, input =>
    {
        if (handler(input) !== false)
        {
            promptInput(prompt, handler);
        }
        else
        {
            rl.close();
        }
    });
}

promptInput('app> ', input =>
{
    switch (input)
    {
        case 'my command':
            // handle this command
            break;
        case 'exit':
            console.log('Bye!');
            return false;
    }
});

Vous pourriez passer une chaîne vide à la place de 'app> ' si votre application imprime déjà quelque chose à l'écran en dehors de cette boucle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X