2011-11-14 5 views
94

私は、コンソール拡張機能を備えた単純なサーバーのhttpサーバーを作ると考えました。スニペットがコマンドラインデータから読み取ることがわかった。対話的にコンソールから値を読み取る

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(); 

    }); 

よく質問しても、私は単にwhile(done) { }ループを使用できませんか?また、問題の時間にサーバーが出力を受け取った場合は、その行を破棄します。

+1

私は 'rl'によってあなたが[readline](https://stackoverflow.com/a/14513763/712526)を意味すると思いますか? – jpaugh

答えて

109

"while(done)"ループを実行することはできません。これは、入力時にブロックする必要があるため、node.jsは実行したくないものです。

var stdin = process.openStdin(); 

stdin.addListener("data", function(d) { 
    // note: d is an object, and when converted to a string it will 
    // end with a linefeed. so we (rather crudely) account for that 
    // with toString() and then trim() 
    console.log("you entered: [" + 
     d.toString().trim() + "]"); 
    }); 
+1

この作品をありがとう、 "終了"リスナーはいくつかの閉鎖操作を呼び出すことができますか、 'さようなら'と言うことができますか? –

+0

例から「終了」リスナーを削除しましたが、正直なところで本当に役立つところはわかりません。 – rob

+0

if文で型付きデータを制御する方法は?またはswtichの場合? –

72

私は、この目的のために別のAPIを使用しました。..

var readline = require('readline'); 
var rl = readline.createInterface(process.stdin, process.stdout); 
rl.setPrompt('guess> '); 
rl.prompt(); 
rl.on('line', function(line) { 
    if (line === "right") rl.close(); 
    rl.prompt(); 
}).on('close',function(){ 
    process.exit(0); 
}); 

これは、までループに促すことができます:代わりに何かが入力されるたびに呼び出されるコールバックを設定

答えはrightです。また、それは素敵なコンソールを提供します。詳細は@http://nodejs.org/api/readline.html#readline_example_tiny_cli

+5

これはすばらしい答えです。明白ではないかもしれませんが(大きなプラスです)、readlineは外部依存関係ではなく、node.jsの一部です。 – jlh

22

Readline APIが12時からかなり変更されました。ドキュメントの標準ストリームからのユーザ入力をキャプチャするには、show有用な例:

const readline = require('readline'); 

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

rl.question('What do you think of Node.js? ', (answer) => { 
    console.log('Thank you for your valuable feedback:', answer); 
    rl.close(); 
}); 

More information here.

+2

これは単なる基本例です。どのようにやりとりしますか?質疑応答?複数の選択肢などがありますか?開いたrlを使用して、一部のロジックを含むユーザーとやりとりする方法がない場合は、一度閉じてrlを再オープンする方法 –

8

@robの答えは、時間のほとんどを動作しますが、あなたは長い入力で期待通りには動作しない場合があります。このソリューションが動作する理由について

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

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

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

説明:あなたが代わりに使用されなければならないものです

バッファのような

addListener('data')作品は、コールバックが呼び出されるとき、それである完全または/およびその入力の終わり。

長い入力はどうですか? 1つの'data'コールバックだけでは不十分です。したがって、2つ以上の部分で入力分割を取得します。それはしばしば便利ではない。

addListener('end')私たちの入力を読んでstdinリーダーが完了したら私たちに通知します。以前のデータを保存しているので、すべてのデータを読み込んで処理することができます。

8

readline-syncを使用してください。これにより、同期コンソールなしでコールバックヘルズを処理できます。でもパスワードで動作します:

var favFood = read.question('What is your favorite food? ', { 
 
    hideEchoBack: true // The typed text on screen is hidden by `*` (default). 
 
});

+0

これは余分な依存関係を必要とします。 –

2

私はノード> =の7.xを使用していると仮定すると、これは現代のasync-await答えに値すると考えています。

答えはまだReadLine::questionですが、while (done) {}が可能なようにラップします。これはOPが明示的に尋ねるものです。

var cl = readln.createInterface(process.stdin, process.stdout); 
var question = function(q) { 
    return new Promise((res, rej) => { 
     cl.question(q, answer => { 
      res(answer); 
     }) 
    }); 
}; 

、その後、例の使用

(async function main() { 
    var answer; 
    while (answer != 'yes') { 
     answer = await question('Are you sure? '); 
    } 
    console.log('finally you are sure!'); 
})(); 

は、アプリは、一般的なプロンプトを表示し、それを処理するのでしょう会話以下

Are you sure? no 
Are you sure? no 
Are you sure? yes 
finally you are sure! 
0

一般的な使用例につながりますswitch文。あなたは、コールバックに自分自身を呼び出しますヘルパー関数を使用してwhileループに行動相当を得ることができ

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; 
    } 
}); 

既にアプリで何かにを印刷した場合は、代わりに'app> 'の空の文字列を渡すことができますこのループの外側のスクリーン。