2017-04-26 2 views
1

Je me demande s'il y a un moyen simple d'obtenir readline « synchrone » ou au moins obtenir l'apparence d'E/S synchrone dans Node.jsComment obtenir synchrone readline, ou "simuler" en utilisant async, dans nodejs?

J'utilise quelque chose comme cela, mais il est assez maladroit

var readline = require('readline'); 
var rl = readline.createInterface({ 
    input: process.stdin, 
    output: process.stdout, 
    terminal: false 
}); 

var i = 0; 
var s1 = ''; 
var s2 = ''; 

rl.on('line', function(line){ 
    if(i==0) { s1 = line; } 
    else if(i==1) { s2 = line; } 
    i++; 
}) 

rl.on('close', function() { 
    //do something with lines 
})' 

Au lieu de cela, je préférerais que ce soit aussi facile que quelque chose comme

var s1 = getline(); // or "await getline()?" 
var s2 = getline(); // or "await getline()?" 

conditions utiles:

(un) Je préfère ne pas utiliser des modules externes ou/dev/stdio filehandle, je soumets le code à un site de soumission de code et ceux-ci ne fonctionnent pas là

(b) Peut utiliser async/Attendent ou générateurs

(c) Dans le cas être en ligne à base

(d) ne devrait pas exiger la lecture entière stdin en mémoire avant le traitement

+0

double possible de [node.js: readSync from stdin?] (http://stackoverflow.com/questions/3430939/node-js-readsync-from-stdin) – supersam654

+0

@ supersam654 J'ai ajouté quelques conditions supplémentaires pour la déduplication. Ma condition est de permettre la lecture de lignes (simples) en utilisant la fonction de type getline en utilisant l'interface readline de manière "synchrone" ou de la simuler en utilisant les fonctions "async/await". –

Répondre

0

Comme je ne sais pas combien de chaînes dont vous avez besoin, je les mets tous dans un tableau

ne hésitez pas commenter si vous avez besoin d'un plus detai conduit réponse ou si ma réponse n'est pas exacte:

var readline = require('readline'); 
var rl = readline.createInterface({ 
    input: process.stdin, 
    output: process.stdout, 
    terminal: false 
}); 

var i = 0; 
var strings = []; 

rl.on('line', function(line) { 
    // 2 lines below are in case you want to stop the interface after 10 lines 
    // if (i == 9) 
    // rl.close() 
    strings[i] = line 
    i++ 
}).on('close', function() { 
    console.log(strings) 
}) 
// this is in case you want to stop the program when you type ctrl + C 
process.on('SIGINT', function() { 
    rl.close() 
}) 
+0

Cela nécessite de lire stdin entier en mémoire, je préférerais que ce n'est pas le cas parce que je lis des fichiers volumineux via stdin et a besoin de streaming –

+0

c'est un flux, donc la seule raison pour laquelle il entre en mémoire est parce que je le mets dans les chaînes variables , mais si vous faites quelque chose d'autre avec elle, il ne va pas dans la mémoire – Amine

+0

Je comprends. Mais je veux quelque chose comme dans perl 'my $ line = <>'. Ou getline en C++. Est-ce si difficile? J'ai l'impression que ma demande n'est pas si farfelue et je la visualise étant complétée par des générateurs ou async/wait –

0

Voici un exemple, mais il faut lire toute stdin avant de donner des résultats mais qui n'est pas idéal

var rl = readline.createInterface({ 
    input: process.stdin, 
    output: process.stdout, 
    terminal: false 
}); 


function lineiterator() { 
    var currLine = 0; 
    var lines = []; 
    return new Promise(function(resolve, reject) { 

     rl.on('line', function (line){ 
      lines.push(line) 
     }) 
     rl.on('close', function() { 
      resolve({ 
       next: function() { 
        return currLine < lines.length ? lines[currLine++]: null; 
       } 
      }); 
     }) 
    }) 
} 

Exemple

lineiterator().then(function(x) { 
    console.log(x.next()) 
    console.log(x.next()) 
}) 

$ echo test$\ntest | node test.js 
test 
test