Node.js - process.stdin.on上的递归函数会产生不必要的重复行为

时间:2017-07-02 19:53:12

标签: javascript node.js recursion

我还是Node.js的初学者。因此,我必须发布整个功能以获得整体视图:

我有这个函数'loopDialog',它接受一个对象和一个起始索引。它启动一个允许用户

的对话框
  1. 提供项目依赖项所需的库名称(通过输入逗号分隔并按Enter键)。
  2. 传递给下一个依赖项(输入'n'并按Enter键)。
  3. 退出(输入'e'并按Enter键)(将其传递给下一个功能)。
  4. 我的问题是,因为我希望流是异步的,所以我尝试通过使其成为递归函数来进行循环。但是,在对话框中按下(n)(将用户传递给下一个依赖项)会显示“你知道系统库...”消息的相同依赖关系n次,其中n是我按下的次数' N”。

    变量'flag'用于克服另一个不希望的行为,即使在退出函数后,只要用户输入任何内容,函数就会继续发送post请求。

    由于某些原因,我无法使用async / await解决此问题。

    有没有其他方法可以避免所有这些问题(或至少解决'n'问题)?

    var request = require('request');
    var qs1 = require('qs');
    
    var oss = process.platform;
    
    process.stdin.resume();
    process.stdin.setEncoding('utf8');
    
    var flag = true;
    var res = {'unrecognized': ['a', 'b', 'c', 'd', 'e', 'f', 'g'], 'dependencies': ['x', 'y', 'z']};
    
    loopDialog (res, 0);
    
    var loopDialog = function (res, i) {
    
        console.log(`Do you know the system libraries needed for: '${res.unrecognized[i]}' ?\n\n`);
        process.stdin.on('data', function(answer) {
            if (!flag) return;
            answer = answer.replace(/ /g, "").replace(/\n/g, "").split(",");
    
            if (answer.length === 0 || answer.length === 1 && answer[0].toLowerCase() === 'e'){
                flag = false;
                checkWhatToInstall(res.dependencies, 0);
            } else {
                if (answer.length === 1 && answer[0].toLowerCase() === 'n') {
                    if ( i < res.unrecognized.length -1) {
                        loopDialog (res, ++i);
                    }
                    else{
                        flag = false;
                        checkWhatToInstall(res.dependencies, 0);
                    }
                } else if (i < res.length){
                    console.log(answer);
                    var x = {form: {packages: res.unrecognized[i], os: oss, pack_type: 'npm', dependencies: answer}};
                    request.post('http://localhost:3000/add', {
                        form: qs1.stringify({
                            package: res.unrecognized[i], os: oss, pack_type: 'npm', dependencies: answer
                        }, {
                            arrayFormat : 'brackets'
                        })}, 
                        function optionalCallback(err, httpResponse, body) {
                            if (err) {
                                console.log(err);
                            }
                            else {
                                res.dependencies.concat(answer);
                                if (i < res.unrecognized.length -1)
                                    loopDialog (res, ++i);
                                else {
                                    flag = false;
                                    checkWhatToInstall (res.dependencies, 0);
                                }
                            }
                    });
                }
            }
        });
    }
    
    var checkWhatToInstall (res, i) {
        console.log('Do something');
    }
    

1 个答案:

答案 0 :(得分:0)

我最终初始化一个全局数组'temp',每当使用res.unrecognized的成员时,它被推送到'temp'然后在函数的第一行中得到条件的评估,这样

....
var temp = [];
var loopDialog = function (res, i) {
    if (!flag || temp.includes(res.unrecognized[i])) return;
    console.log(`Do you know the system libraries needed for: '${res.unrecognized[i]}' ?\n\n`);
    temp.push(res.unrecognized[i]);
   ...
}
....

注意:我仍在寻找更好的方法。