Javascript 在通过管道将stdin传输到stdout后,如何重置stdin?

Javascript 在通过管道将stdin传输到stdout后,如何重置stdin?,javascript,node.js,io,stream,node.js-stream,Javascript,Node.js,Io,Stream,Node.js Stream,你好,首先问你一个问题!无论如何,我正在写一个小实验来帮助更好地掌握流和更复杂的组合流和承诺 然而,我遇到了一个我目前无法解决的问题。如果运行下面的脚本,然后输入input,然后按ctrl-d结束输入:节点将根据需要尝试从stdin中读取,但由于stdin已结束,因此会立即关闭那么有没有更好的方法来写这个?或者有没有办法重置stdin流以再次获取输入?还是有更好的方法停止请求输入,等待结束事件解决我的承诺? 另请注意:在节点5.1.0上运行,使用ES2015(通过Babel 6) import

你好,首先问你一个问题!无论如何,我正在写一个小实验来帮助更好地掌握流和更复杂的组合流和承诺

然而,我遇到了一个我目前无法解决的问题。如果运行下面的脚本,然后输入input,然后按ctrl-d结束输入:节点将根据需要尝试从stdin中读取,但由于stdin已结束,因此会立即关闭那么有没有更好的方法来写这个?或者有没有办法重置stdin流以再次获取输入?还是有更好的方法停止请求输入,等待结束事件解决我的承诺?

另请注意:在节点5.1.0上运行,使用ES2015(通过Babel 6)

import { Transform, Writable } from 'stream';
import util from 'util';

/**
 * Generic Transform
 * A test class to expiriment with creating a series of transforms
 *
 * @class
 * @extends {stream.Transform}
 */
class GenericTransform extends Transform {
  constructor (transformCallback, options={}) {
    super(Object.assign({}, options, { objectMode: true }));
    this._transformCallback = transformCallback;
  }

  /**
   * Transform
   * Stream method to transform read data, transform it, then move it to
   * the next stream.
   *
   * @method
   * @param {buffer} chunk - Buffer read from the input stream
   * @param {string} enc - Encoding of the input stream chunk buffer
   * @param {function} done - Callback to fire when transform is complete
   */
  _transform (chunk, enc, done) {
    try {
      this.push(this._transformCallback(chunk, this));
      done();
    }
    catch (e) {
      this.emit('error', e);
      done(e);
    }
  }
}

/**
 * Stdout Writer
 * Handles writing to stdout including linebreaks. I believe this is
 * required as writing to the stdout stream will not emit end\finish events.
 *
 * @class
 * @extends {stream.Writable}
 */
class StdoutWriter extends Writable {
  constructor (options) {
    super(options);
  }

  /**
   * Write
   * Stream method to write to process.stdout
   *
   * @method
   * @param {buffer} chunk - Text that gets written to the console
   * @param {string} enc - Encoding of the buffer
   * @param {callback} done - Callback to call when finished
   */
  _write (chunk, enc, done) {
    process.stdout.write(String(chunk) + '\n');
    done();
  }
}

/**
 * To
 * A shorthand function to create a generic transform method
 *
 * @method
 * @public
 * @param {function} transformer - transformer(data) returns new data
 * @returns {GenericTransform} A generic transform stream
 */
function to (transformer) {
  return new GenericTransform(transformer);
}

/**
 * Prompt
 * Requests input from the user then transforms it. Ideally it would ask for
 * input. When it receives a line it would stop reading, transform the data
 * then when the stream is finished ask the user for more input.
 *
 * @returns {Promise} A promise when the input has been read, transformed,
 *                    and displayed to the console via process.stdout.write
 */
function prompt () {
  process.stdout.write('Enter some input: ');
  return new Promise((resolve, reject) => {
    /** Start with process.stdin input stream */
    process.stdin

      /**
       * Converts the raw string input into a simple object with
       * a contents property and a date property
       *
       * @example
       * > Test
       * > (ctrl-d)
       *  {contents: "Test", date: 43993991013 }
       */
      .pipe(to((chunk) => {
        return {
          contents: String(chunk).trim(),
          date: Date.now()
        };
      }))

      /**
       * Takes the object created from the previous step and formats it as
       * a string using the inspect util. I suppose JSON.stringify would
       * also have worked.
       */
      .pipe(to((obj) => {
        return util.inspect(obj);
      }))

      /**
       * Pipe to a writable stream that writes to stdout. This is necessary
       * because the docs say that stdout never emit finish or end events.
       */
      .pipe(new StdoutWriter())

      /**
       * Handle errors and finish events by either resolving or rejecting
       * the parent promise object.
       */
      .on('finish', resolve)
      .on('error', reject);
  });
}

/** Set the encoding so it all comes in as strings */
process.stdin.setEncoding('utf8');

/**
 * This is the main driver logic for connecting the above pieces. It will
 * input the first question then keeps asking for more input. To stop
 * entering data press ctrl-d to send an EOF to process.stdin. This
 * at least causes the finish event to fire at the end but on the next
 * usage of prompt, everything is done.
 */
prompt()
  .then(prompt);