質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
npm

npmは、Node Packaged Modulesの略。Node.jsのライブラリ・パッケージを管理できるツールです。様々なモジュールを簡単にインストールでき、自分でモジュールを作成し公開する際にも使用できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1210閲覧

'enquirer'というnpmでのプロンプトの処理の後で標準入力を扱いたいです。

unstoppa61e

総合スコア15

npm

npmは、Node Packaged Modulesの略。Node.jsのライブラリ・パッケージを管理できるツールです。様々なモジュールを簡単にインストールでき、自分でモジュールを作成し公開する際にも使用できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/11/15 22:49

編集2021/11/17 05:00

プログラムの概要

Node.js にて、円周率の暗記を手助けするプログラムを書いています。

発生する問題

enquirer という npm を使用しており、以下のようなプロンプトからモードセレクトに移行させるという流れになっています。

>>>>>>>>>> PI GAME <<<<<<<<<< ? Select your mode: … ❯ PRACTICE MODE REAL MODE SHOW PI DIGITS HIGH SCORES

しかしながら、モード選択後に標準入力を受け取りたいのに、入力を待たずにプログラムが終了してしまいます。

原因の予想

enquirerによって用意したモードセレクトをスキップして、いきなりモードを始めると、意図通りに標準入力を受け付けてくれます。
そのため、原因は、enquirerにより標準入力に関係する何らかの状態が初期状態から変更されてしまった状態のままで、標準入力に関係する処理を実行していることにあるように思います。

お教え頂きたいこと

プロンプトでの選択後、enquirerでの処理による変更を初期状態に戻して、選択したモードに移行するような方法はありますでしょうか?
それが難しければ、モード選択後に、標準入力を適切に扱うような方法があれば、ご教示頂きたいです。
どうぞよろしくお願い致します。

実際のコード

#!/usr/bin/env node 'use strict' { const { Select } = require('enquirer') const chalk = require('chalk') const PI_START_TEXT = '3.' const PI_BELOW_THE_DECIMAL_POINT = '1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679' class PracticeMode { start () { const instruction = 'Keep typing in the number which fits the cursor position.' // この行の出力処理の直後に、プログラムが止まってしまう process.stdout.write(chalk.bold.green(instruction) + '\n\n' + PI_START_TEXT) const readline = require('readline'); readline.emitKeypressEvents(process.stdin) process.stdin.setRawMode(true); let currentIndex = 0 process.stdin.on('keypress', (char, key) => { if (key.ctrl && key.name === 'c') { process.exit(); } else if (currentIndex === 100) { this.putsCongratulations() process.exit(); } else if (char === PI_BELOW_THE_DECIMAL_POINT[currentIndex]) { process.stdout.write(char) currentIndex++ } else { const scoreMessage = `Your score: ${currentIndex}` const remaining_digits_text = this.make_remaining_digits_text(currentIndex) console.log(chalk.red(remaining_digits_text) + '\n' + scoreMessage) process.exit(); } }) } putsCongratulations () { const headSpaces = ' '.repeat(6) const congratulationsSentences = [ 'Congratulations!', 'You have memorized the first 100 digits of pi.' ] let congratulations = '' congratulationsSentences.forEach(sentence => { congratulations += headSpaces + sentence + '\n' }) console.log(chalk.bold.green(congratulations)) } make_remaining_digits_text (currentIndex) { let remaining_digits_text = '' const digitsNum = 100 const sectionDigitsNum = 10 const lineDigitsNum = 50 for (let i = currentIndex; i < digitsNum; i++) { if (i === lineDigitsNum) { remaining_digits_text += '\n' + ' '.repeat(PI_START_TEXT.length) } else if (i % sectionDigitsNum === 0) { remaining_digits_text += ' ' } remaining_digits_text += PI_BELOW_THE_DECIMAL_POINT[i] } return remaining_digits_text } } class Game { constructor () { this.practiceMode = 'PRACTICE MODE' this.showPiDigits = 'SHOW PI DIGITS' this.highScores = 'HIGH SCORES' } start () { const modes = [ { name: this.practiceMode, explanation: 'Check how many digits of pi you can name from the point you designated.' }, { name: this.showPiDigits, explanation: 'Check the first 100 digits of pi.' }, { name: this.highScores, explanation: 'Check the high scores.' } ] const prompt = new Select({ name: 'mode', message: 'Select your mode:', choices: modes.map(mode => mode.name), footer () { const explanations = modes.map(mode => ' '.repeat(2) + mode.explanation) return chalk.green('\n' + explanations[this.index]) } }) prompt.run() .then(answer => { switch (answer) { case this.practiceMode: // 問題が起こっているのは、この PRACTICE MODE 選択時 new PracticeMode().start() break; case this.showPiDigits: break; case this.highScores: break; } }) } } function main () { const welcomeMessage = '>'.repeat(10) + ' PI GAME ' + '<'.repeat(10) console.log(chalk.bold.green(welcomeMessage)) // これが意図通りに動かない new Game().start() // この行を実行すれば、意図通りに動く // new PracticeMode().start() } main() }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

js

1process.stdin.on('keypress', (char, key) ...

の直前に

js

1process.stdin.resume()

を入れるとどうでしょうか?

参考: Node.js のプロセス処理を少し学ぶ - ashiris’s diary

投稿2021/11/17 07:59

obregonia1

総合スコア20

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問