Node.js的多个菜单

时间:2015-09-08 12:54:56

标签: javascript node.js npm

如何使用Node.js创建多个菜单。我已经在https://nodejs.org/api/process.html#process_process_stdin找到了文档,并在我的示例中使用了大部分文档。

问题是在下一个菜单showSub中,主菜单仍然是监听器。当我尝试process.stdin.pauseprocess.stdin.end之类的内容时,它会退出我的代码。

旁注:我不想使用任何依赖项。谢谢你的帮助!

这是一个例子:

// Main
function showMain() {
    console.log(
        '1 = Show sub' + '\n' +
        '2 = Show other sub blabla...'  + '\n' +
        '3 = Exit'  + '\n\n' +
        'Choose number, then press ENTER:'
        );
    process.stdin.setEncoding('utf8');
    process.stdin.on('readable', checkMenu);

    function checkMenu() {
        var input = process.stdin.read();
        if(input !== null) {
            switch(input.trim()) {
                case '1': showSub(); break;
                case '2': showOtherSubBlaBla; break;
                case '3': process.exit(); break;
                default: showMain();
            }
        }
    }
}

// Sub
function showSub() {
    // process.stdin.pause(); Do I need this somewhere? It should not exit my code
    console.log(
        '1 = Do something bla bla' + '\n' +
        '2 = Go back to main'  + '\n\n' +
        'Choose number, then press ENTER:'
        );
    process.stdin.setEncoding('utf8');
    process.stdin.on('readable', checkMenu);

    function checkMenu() {
        var input = process.stdin.read();
        if(input !== null) {
            switch(input.trim()) {
                case '1': doSomethingBlaBla(); break;
                case '2': showMain; break;
                default: showSub();
            }
        }
    }
}

showMain();

2 个答案:

答案 0 :(得分:2)

也许这个解决方案仍然可以更加优雅,但它应该可行。 为stdin流创建一个全局处理程序,并根据您的需要将其指向不同的实现,如下所示:

var menuHandler;

// Initialize
function initialize() {
    showMain();
    process.stdin.setEncoding('utf8');
    process.stdin.on('readable', checkMenu);

    function checkMenu() {
        var input = process.stdin.read();
        if(input !== null) {
            menuHandler(input.trim());
        }
    }
}

// Main
function showMain() {
    console.log(
        '1 = Show sub' + '\n' +
        '2 = Show other sub blabla...'  + '\n' +
        '3 = Exit'  + '\n\n' +
        'Choose number, then press ENTER:'
        );

    menuHandler = function(input){
        switch(input) {
            case '1': showSub(); break;
            case '2': showOtherSubBlaBla; break;
            case '3': process.exit(); break;
            default: showMain();
        }
    };
}

// Sub
function showSub() {
    console.log(
        '1 = Do something bla bla' + '\n' +
        '2 = Go back to main'  + '\n\n' +
        'Choose number, then press ENTER:'
        );

    menuHandler = function(input){
        switch(input) {
            case '1': doSomethingBlaBla(); break;
            case '2': showMain(); break;
            default: showSub();
        }
    };
}

initialize();

答案 1 :(得分:0)

我找到了一个非常好的解决方案。 Node.js最近推出了v4.0.0。现在,您可以使用模块readline

轻松创建菜单

在此处阅读更多内容:https://nodejs.org/api/readline.html

我也做了一个工作样本:

// Requires readline and create global variable menu
var readline = require('readline'),
    menu;

// Main
function showMain() {
    // Clear screen
    process.stdout.write('\033c');

    // Log the menu
    console.log(
        'Main menu\n\n' +
        '1 = Go to sub\n' +
        '2 = Can be another sub... For now same as option 1\n' +
        '3 = Exit'
        );

    // Check if there is already a menu active. If true, close it.
    if(menu) menu.close();

    //Creates a readline Interface instance
    menu = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    // Ask question
    menu.question('Where to go? ', function(input) {
        switch(input) {
            case '1': showSub(); break;
            case '2': showSub(); break;
            case '3': process.exit(); break;
            default: showMain() /* show menu again if input does not match */;
        }
    });
}

// Sub
function showSub() {
    // Clear screen
    process.stdout.write('\033c');

    // Log the menu
    console.log(
        'Sub menu\n\n' +
        '1 = Another sub blabla...\n' +
        '2 = Go back to main'
        );

    // Check if there is already a menu active. If true, close it.
    if(menu) menu.close();

    // Creates a readline Interface instance
    menu = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    // Ask question
    menu.question('Where to go? ', function(input) {
        switch(input) {
            case '1': console.log('Another sub blabla...'); break;
            case '2': showMain(); break;
            default: showSub() /* show menu again if input does not match */;
        }
    });
}

showMain();