【问题标题】:Node.Js function runs twice when called once on promise returnNode.Js 函数在 promise 返回时调用一次时运行两次
【发布时间】:2018-11-09 06:41:33
【问题描述】:

我正在尝试根据用户输入创建所需数量的 Google 幻灯片。理论上,如果我能解决这个问题,我的代码应该可以工作。问题是,我做不到。当我运行我的代码时,它会停止,因为 createSlide() 函数在一次调用中运行两次,并创建了两张具有相同 ID 的幻灯片。在网上四处寻找,我只发现了有关从浏览器输入的 Node.Js 的内容。第一次通过它运行正常,它完成了它应该做的事情,但是当第二张幻灯片(id:slide_1)被创建时,它会制作幻灯片,将文本加倍,例如:

Hi
bye

会创造

Hi
bye
Hi
bye

然后停止,因为不可能有两个相同的 Id。这是我的代码(因为幻灯片创建工作正常,我已经删除了请求):

function askYOrN(auth){

    console.log("HELLO");

    const r4 = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    r4.question("Do you want to add a slide [Y/N]? ", function(yesOrNo){
        yesOrNoLog = yesOrNo;
        r4.close();
        fAskForNewCounter = fAskForNewCounter + 1;
        askForNew(auth);
    });
}

//ASKS IF ANOTHER SLIDE IS NEEDED
function askForNew(auth){

    //READLINE
    const r5 = readline.createInterface({
        input: process.stdin,
        output: process.stdout, 
        terminal: false
    });

    //CLEARS txt
    txtArray = [];

    //CHECKS THE ANSWER AND DOES ACCORDINGLY
    if (yesOrNoLog == "yes" || yesOrNoLog == "y"){

        //ASKS FOR TEXT AND ASSIGNS IT TO THE VARIABLE
        r5.prompt();
        console.log("Text:\n");
        r5.on('line', function (textIn) {
            if (textIn == ".exit" || textIn == ".e" || textIn == ".next" || textIn == ".n"){
                createSlide(auth);
            }else{
                textArray.push(textIn);
                textArray.push('\n');
            }
        }); 
    }else if (yesOrNoLog == "no" || yesOrNoLog == "n"){

        //CREATES TITLE SLIDE
        createTitleSlide(auth);
    }else{

        //ASKS FOR VALID ANSWER
        if (fAskForNewCounter >= 0){
            console.log("Enter a valid answer");
            askYOrN(auth);
        }
    }
}

//DECLARATION FOR THE NUMBER COUNTER [ num ]
var num = 0;

function createSlide(auth) {

    //AUTHENTICATION
    const slides = google.slides({version: 'v1', auth});

    //CHANGES txtArray TO STRING
    var txt = txtArray.join('');

    //CHANGING VARS
    var slideId = 'slide_' + num;
    var pageId = slideId;

    var textId = 'text_box_' + num;
    var elementId = textId;

    var iIndex = num;

    //SLIDE NUMBER
    var sNum = num + 1;


        console.log(pageId);

    //ALL REQUESTS GO IN requests
         var requests = [{   
        }];

    //BATCH UPDATE
    return slides.presentations.batchUpdate({
        presentationId,
        resource: {
            requests,
        },
    }, (err, res) => {
        if (err) {
            error(err);
        }else{
            console.log("Slide #" + sNum + " has been created");

            //INCREASES COUNTER BY 1
            num = num + 1;

            //ASKS IF A NEW SLIDE WANTS TO BE CREATED
            var delay = 30;
            var lastClick = 0;

            if (lastClick >= (Date.now() - delay))
            return;
            lastClick = Date.now();

            yesOrNoLog = "";
            askYOrNo(auth);
        }
    });
}

提前感谢您的帮助!

编辑
我做了更多的工作,发现在我的代码中 r5.on 运行了两次。我尝试删除 array.push("\n")。但这并不能解决问题。数组输出为

[hi, bye, hi, bye]

这是我再次删除请求的新代码:

//ASKS IF YOU WANT A NEW SLIDE
function askYOrN(auth){

    console.log("askYOrN");

    const r4 = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
        terminal: false
    });

    r4.question("Do you want to add a slide [Y/N]? ", function(yesOrNo){
        console.log("aksYOrN question");
        yesOrNoLog = yesOrNo;
        r4.close();
        yOrNCheckCounter = yOrNCheckCounter + 1;
        askYOrNCheck(auth);
    });
}

//ASKS IF ANOTHER SLIDE IS NEEDED
function askYOrNCheck(auth){
    console.log("askYOrNCheck begins");
    //READLINE
    const r5 = readline.createInterface({
        input: process.stdin,
        output: process.stdout, 
        terminal: false
    });

    //CLEARS TXT
    txtArray = [];

    //CHECKS THE ANSWER AND DOES ACCORDINGLY
    if (yesOrNoLog == "yes" || yesOrNoLog == "y"){

        //ASKS FOR TXT AND ASSIGNS IT TO THE VARIABLE
        console.log("prompt opens");
        r5.prompt();
        console.log("Text:");
        r5.on('line', function (textIn) {
            console.log("r5.on");
            if (textIn == ".exit" || textIn == ".e" || textIn == ".next" || textIn == ".n"){
                console.log("if next");
                createSlide(auth);
            }else{
                console.log(txtArray);
                console.log("about to push text");
                txtArray.push(textIn);
                console.log(txtArray);
            }
        }); 
    }else if (yesOrNoLog == "no" || yesOrNoLog == "n"){

        //CREATES TITLE SLIDE
        createTitleSlide(auth);
    }else{

        //ASKS FOR VALID ANSWER
        if (yOrNCheckCounter >= 0){
            console.log("Enter a valid answer");
            askYOrN(auth);
        }
    }
}

//DECLARATION FOR THE NUMBER COUNTER [ num ]
var num = 0;

function createSlide(auth) {

    //AUTHENTICATION
    const slides = google.slides({version: 'v1', auth});

    //CHANGES txtArray TO STRING
    var text = txtArray.join('\n');

    //CHANGING VARS
    var slideId = 'slide_' + num;
    var pageId = slideId;

    var textId = 'text_box_' + num;
    var elementId = textId;

    var iIndex = num;

    //SLIDE NUMBER
    var sNum = num + 1;

    console.log(pageId);

    //ALL REQUESTS GO IN [ requests ]
            var requests = [];

    //BATCH UPDATE
    return slides.presentations.batchUpdate({
        presentationId,
        resource: {
            requests,
        },
    }, (err, res) => {
        if (err) return error(err);
        console.log("Slide #" + sNum + " has been created");

        //INCREASES COUNTER BY 1
        num = num + 1;

        //ASKS IF A NEW SLIDE WANTS TO BE CREATED
        askYOrN(auth);
    });
}

注意: 我将 askForNew() 重命名为 askYOrNoCheck()。

再次感谢您的帮助。

【问题讨论】:

  • 我强烈推荐查看Inquirer
  • 首先,我建议摆脱你的全局变量。如果不看代码,它可能会导致您当前的问题或未来的问题。相反,传递必要的变量(例如checkAnswer(providedAnswer) { /* ... */ })。其次,确保将您的函数分成有意义的单元。例如,askYOrNCheck() 执行 2 个操作:检查用户的答案和提示输入幻灯片文本。这将帮助你更清楚地思考你在做什么。第三,考虑重新访问你的名字(例如,askYOrNCheck 应该是 checkAnswer)。
  • 最后一个技巧让函数的意图更加清晰。前几次我读它时,我以为你会提示用户回答。虽然这些并不能解决您的问题,但解决它们将使其他人更容易帮助您,并且可能帮助您自己弄清楚发生了什么,因为您的程序将更具语义意义和更好的定义。
  • 实际上,如果用户输入yesyfalse 如果用户输入,您可能想要使用类似shouldAddSlide(providedAnswer) 的东西,而不是checkAnswer,返回true non,如果用户输入其他任何内容,则会引发错误。
  • @c1moore 感谢您的建议,我一定会通过我的代码。但是我发现了问题,我忘记关闭 readline 所以它推送 2 个答案而不是 1 个。

标签: javascript node.js google-slides-api


【解决方案1】:

需要添加r5.close()。它从一个输入中获取多个输入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 2021-12-06
    • 2017-11-05
    • 1970-01-01
    • 2017-09-24
    相关资源
    最近更新 更多