En attente de l'utilisateur pour entrer l'entrée dans Node.js
Je comprends la raison Node.js pour les événements asynchrones et j'apprends à écrire le code de cette façon. Cependant, je suis coincé avec la situation suivante:
Je veux écrire du code que de temps en temps des pauses pour la saisie de l'utilisateur.
Le programme n'est pas conçu comme un serveur (même si actuellement il est prévu pour la ligne de commande). Je réalise que c'est atypique utilisation de Nœud. Mon objectif est de migrer le programme de retour à côté client Javascript de l'application, mais je trouve que travailler dans Node.js pour être à la fois fascinant et très utile pour le débogage. Cela me ramène à mon exemple qui illustre bien le problème:
Il lit dans un fichier texte et les sorties de chaque ligne, à moins que la ligne se termine par un "?". Dans ce cas, il doit se mettre en pause pour l'utilisateur de préciser ce qu'on entend par cette ligne. Actuellement mon programme de sorties toutes les lignes de la première et attend des précisions à la fin.
Est-il de toute façon à force node.js la pause de ligne de commande d'entrée, précisément pour le cas où la condition des feux (c'est à dire, où la ligne se termine par un "?")?
var fs = require("fs");
var filename = "";
var i = 0;
var lines = [];
//modeled on http://st-on-it.blogspot.com/2011/05/how-to-read-user-input-with-nodejs.html
var query = function(text, callback) {
process.stdin.resume();
process.stdout.write("Please clarify what was meant by: " + text);
process.stdin.once("data", function(data) {
callback(data.toString().trim());
});
};
if (process.argv.length > 2) {
filename = process.argv[2];
fs.readFile(filename, "ascii", function(err, data) {
if (err) {
console.error("" + err);
process.exit(1);
}
lines = data.split("\n");
for (i = 0; i < lines.length; i++) {
if (/\?$/.test(lines[i])) { //ask user for clarification
query(lines[i], function(response) {
console.log(response);
process.stdin.pause();
});
}
else {
console.log(lines[i]);
}
}
});
}
else {
console.error("File name must be supplied on command line.");
process.exit(1);
}
source d'informationauteur blandish
Vous devez vous connecter pour publier un commentaire.
L'astuce est de ne pas le faire itteratively, mais ne la boucle récursive. De sorte que la ligne suivante est imprimé dans un rappel, qui est appelé Un: après la ligne est imprimé, ou B: a l'entrée de la console a été traitée.
C'est une bonne solution pour deux raisons:
Il n'y a pas de itératif d'attente pour la boucle et un seul async tâche d'être lancé par matrice de lignes que vous avez. Si, dans votre version, vous avez eu des millions de lignes? Vous avez lancé des millions de async sorties instantanément... MAUVAIS!
La méthode récursive permet non seulement de mieux de la concurrence des autres async travail que vous voulez faire, mais vous n'avez pas obstruer la boucle d'événements avec mini async des tâches à partir d'un appel de fonction. Cela peut provoquer des problèmes de mémoire, la dégradation de la performance, et d'autres questions digne d'éviter, notamment sur les grandes entrées.
J'ai trouvé un module qui fait ça très simplement par oui ou non:
https://www.npmjs.com/package/cli-interact
Installer:
npm install cli-interact --save-dev
Comment utiliser est pris directement à partir de la ngp site:
Voici un autre moyen qui n'a pas de dépendances (readline est intégré)