简体   繁体   English

有没有办法使用“询问者”npm 处理标准输入?

[英]Is there a way to handle standard input using "enquirer" npm?

Program Overview计划概述

I've been writing a program to help its user memorize digits of pi.我一直在编写一个程序来帮助它的用户记住 pi 的数字。

Problems encountered遇到的问题

The program includes the following prompt which is offered by enquirer npm.该程序包括由enquirer npm 提供的以下提示。

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

I want to receive standard input after mode selection, but the programs exits without waiting.我想在模式选择后接收标准输入,但程序无需等待就退出。

Predicted Cause预测原因

If you skip the mode select offered by enquirer and start the mode directly, the program accepts standard input as intended.如果您跳过询问者提供的模式选择并直接启动模式,程序将按预期接受标准输入。 Therefore, the cause seems to be that the process related to the standard input is being executed while some state related to it has been changed from the initial state by enquirer.因此,原因似乎是与标准输入相关的进程正在执行,而与其相关的某些状态已被查询者从初始状态更改。

What I need to know我需要知道的

Is there any way to reset the changes made by enquirer to the initial state and move to the selected mode?有什么方法可以将查询者所做的更改重置为初始状态并移动到所选模式? If this is difficult, I would like to know if there is a way to handle the standard input properly after selecting the mode.如果这很难,我想知道是否有办法在选择模式后正确处理标准输入。 Thank you very much beforehand.事先非常感谢。

Code代码

#!/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.'
      // This program stops after executing the next line.
      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:
              // I have the problem here.
              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))

    // This doesn't work as intended.
    new Game().start()

    // If you run the next line instead, it works as intended.
    // new PracticeMode().start()
  }

  main()
}

Insert a line as follows:插入一行如下:

    let currentIndex = 0
    process.stdin.resume()
    process.stdin.on('keypress', (char, key) => {

ref: Node.js のプロセス処理を少し学ぶ - ashiris's diary ref: Node.js のプロセス处理少し学ぶ - ashiris 的日记

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM