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

Po prostu wypróbowałem ten kod, ale zamiast tego wprowadzono dane jeden po drugim, migając wiersz "Command:". Wiem, że node.js nie jest blokowany, ale nie wiem, jak rozwiązać ten problem.Jak odczytywać w nieskończoność w pliku Node.js

Odpowiedz

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 

Kluczem jest, aby nie używać synchronicznych pętli. Powinniśmy zapytać następnego rl.question dopiero po rozpatrzeniu odpowiedzi. Rekurencja jest drogą do zrobienia. Definiujemy funkcję, która zadaje pytanie i obsługuje odpowiedź, a następnie wywołuje ją od wewnątrz po obsłudze odpowiedzi. W ten sposób zaczynamy od początku, tak jak w przypadku zwykłej pętli. Ale pętle nie dbają o kod ansyc, podczas gdy nasza implementacja się troszczy.

+0

co się dzieje kiedy zadzwonić readline.question() ponownie, zanim użytkownik odpowiedzi na poprzedniej rozmowy? –

+0

Nie jestem ekspertem od węzła lub js - ale wyobrażam sobie, że "następny" konkuruje o interfejs; więc tylko jeden może pisać na raz (i ten sam otrzymuje odpowiedź pod warunkiem, że jest obsługiwany w oddzwanianiu). Gdy się zakończy, następny czeka. – OJFord

+1

Działa to, ale dodaje nowy stos wywołań za każdym razem, gdy wprowadzono polecenie, a zatem może dojść do stackoverflow, jeśli wprowadzono zbyt wiele poleceń. Czy nie istnieje rozwiązanie stałego stosu przy użyciu rl.question()? – Javarome

10

Inną opcją, poprzez dokumentacji node.js, jest użycie events:

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

Dzięki, to działa dobrze dla tego, co próbowałem zrobić. Mam połączenie TCP z opcjami zwrotnymi opartymi na zdarzeniach. Miło móc to zrobić z wydarzeniami zamiast z pętlami. :-) – r0ber7