2014-06-28 14 views
5
while(1){ 
    rl.question("Command: ",function(answer){ 
    console.log(answer); 
    }) 
} 

Probieren Sie einfach diesen Code, aber erhalten Sie die Eingabe nacheinander, es blinkt die "Command:" Zeile. Ich weiß, dass node.js nicht blockiert ist, aber ich weiß nicht, wie ich diese Probleme beheben kann.So lesen Sie endlos in Node.js

Antwort

13
var readline = require('readline'); 
var log = console.log; 

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

var recursiveAsyncReadLine = function() { 
    rl.question('Command: ', function (answer) { 
    if (answer == 'exit') //we need some base case, for recursion 
     return rl.close(); //closing RL and returning from function. 
    log('Got it! Your answer was: "', answer, '"'); 
    recursiveAsyncReadLine(); //Calling this function again to ask new question 
    }); 
}; 

recursiveAsyncReadLine(); //we have to actually start our recursion somehow 

Der Schlüssel ist, keine synchronen Schleifen zu verwenden. Wir sollten als nächstes rl.question nur nach dem Beantworten fragen. Rekursion ist der Weg zu gehen. Wir definieren eine Funktion, die die Frage stellt und die Antwort behandelt, und rufen sie dann nach der Antwortbehandlung von innen heraus auf. So fangen wir von vorne an, genau wie bei der normalen Schleife. Schleifen kümmern sich jedoch nicht um den anysyc-Code, während sich unsere Implementierung darum kümmert.

+0

was, wenn Sie readline.question() erneut, bevor der Benutzer reagieren auf einen vorherigen Anruf rufen geschieht dann? –

+0

Ich bin kein Experte für Knoten oder js - aber ich stelle mir vor, die "nächste" konkurriert um die Schnittstelle; also kann nur einer auf einmal schreiben (und derselbe bekommt die Antwort, vorausgesetzt, er wird im Callback behandelt). Wenn es fertig ist, wartet der nächste. – OJFord

+1

Dies funktioniert, aber dies fügt jedes Mal, wenn ein Befehl eingegeben wird, einen neuen Aufrufstack hinzu, wodurch möglicherweise ein Stapelüberlauf erreicht wird, wenn zu viele Befehle eingegeben werden. Gibt es keine Konstant-Stack-Lösung mit rl.question()? – Javarome

10

Eine weitere Möglichkeit, über die Node.js Dokumentation ist events zu verwenden:

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

rl.setPrompt('OHAI> '); 
rl.prompt(); 

rl.on('line', function(line) { 
    switch(line.trim()) { 
     case 'hello': 
      console.log('world!'); 
      break; 
     default: 
      console.log('Say what? I might have heard `' + line.trim() + '`'); 
     break; 
    } 
    rl.prompt(); 
}).on('close', function() { 
    console.log('Have a great day!'); 
    process.exit(0); 
}); 
+0

Danke, das funktioniert gut für das, was ich versuchte zu tun. Ich habe eine TCP-Verbindung mit ereignisbasierten Callbacks. Schön, dass ich das mit Events statt mit Loops machen kann. :-) – r0ber7