阻止Node.js中的stdin

Jos*_*shJ 2 stdin blocking node.js

简短说明:

我正在尝试编写一个简单的游戏Node.js,需要在每个回合等待用户输入.我如何avoid callback在一个转弯循环内部地狱(例如凌乱的代码),每个转弯循环迭代需要阻止并等待来自标准输入的输入?

很长的解释:

当有人要求阻止stdin输入时,我在StackOverflow上读到的所有解释似乎都是"那不是Node.js的意思!"

我知道Node.js设计为非阻塞,我也理解为什么.但是我觉得它让我陷入困境和如何解决这个问题的困难之中.我觉得我有三个选择:

  1. 找到一种方法来阻止stdin并保留我的while循环
  2. 抛弃while循环,而不是每当前一轮结束时递归调用一个方法(如nextTurn).
  3. 抛弃while循环,而不是每当转弯结束时使用setTimeout(0,...)或类似的东西来调用方法(如nextTurn).

使用选项(1),我将反对Node.js非阻塞IO的原则.使用选项(2),我将最终达到堆栈溢出,因为每次调用都会向调用堆栈添加另一个转弯.使用选项(3),我的代码最终会变得混乱.

在Node.js内部有默认函数,标记为**Sync(例如,参见fs库或sleep函数),我想知道为什么没有用于获取用户输入的Sync方法?如果我要写一些类似于fs.readSync我将如何去做并仍然遵循最佳实践的东西?

Art*_*are 11

刚刚发现:https: //www.npmjs.com/package/readline-sync

示例代码(完成后npm install readline-sync)

var readlineSync = require('readline-sync');
while(true) {
  var yn = readlineSync.question("Do you like having tools that let you code how you want, rather than how their authors wanted?");
  if(yn === 'y') {
    console.log("Hooray!");
  } else {
    console.log("Back to callback world, I guess...");
    process.exit();
  }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止唯一的问题是"这不是如何使用节点!" 合唱,但我有耳塞:)


Tim*_*ple 5

我同意关于转向基于事件的系统的评论,并会抛弃循环。我已经拼凑了一个基于文本处理的快速示例,可用于简单的文本游戏。

var fs = require('fs'),
    es = require('event-stream');

process.stdin
    .pipe(es.split())
    .on('data', parseCommand);

var actionHandlers = {};

function parseCommand(command) {
    var words = command.split(' '),
        action = '';

    if(words.length > 1) {
        action = words.shift();
    }

    if(actionHandlers[action]) {
        actionHandlers[action](words);
    } else {
        invalidAction(action);
    }
}

function invalidAction(action) {
    console.log('Unknown Action:', action);
}

actionHandlers['move'] = function(words) {
    console.log('You move', words);
}

actionHandlers['attack'] = function(words) {
    console.log('You attack', words);
}
Run Code Online (Sandbox Code Playgroud)

您现在可以将您的操作分解为离散函数,您可以使用中央 actionHandlers 变量注册这些函数。这使得添加新命令几乎变得微不足道。如果您可以添加一些有关为什么上述方法对您不起作用的详细信息,请告诉我,我会修改答案。