Функция Node.Js запускается дважды, когда вызывается один раз при возврате обещания

Я пытаюсь создать столько слайдов Google Slide, сколько необходимо, на основе пользовательского ввода. Теоретически мой код должен работать, если я смогу решить эту проблему. Проблема в том, что я не могу. Когда я запускаю свой код, он останавливается, потому что функция createSlide() запускается дважды при одном вызове и создает два слайда с одним и тем же идентификатором. Покопавшись в Интернете, я нашел сведения о вводе Node.Js только из браузера. В первый раз он работает нормально, он делает то, что должен, но когда создается второй слайд (id: slide_1), он делает слайд, удваивает текст, например:

Hi
bye

Создал бы

Hi
bye
Hi
bye

Затем остановитесь из-за того, что не может быть двух одинаковых идентификаторов. Вот мой код (я удалил запросы, так как создание слайдов работает нормально):

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);
        }
    });
}

Заранее спасибо за вашу помощь!

EDIT
Я проделал дополнительную работу и обнаружил, что в моем коде 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().

Еще раз спасибо за вашу помощь.


person Arkin Solomon    schedule 09.11.2018    source источник
comment
Я настоятельно рекомендую проверить Inquirer   -  person Goodbye StackExchange    schedule 13.11.2018
comment
Во-первых, я бы предложил избавиться от ваших глобальных переменных. Если не вчитываться в код, это может вызвать либо текущую проблему, либо проблемы в будущем. Вместо этого передайте необходимые переменные (например, checkAnswer(providedAnswer) { /* ... */ }). Во-вторых, обязательно разделите свои функции на осмысленные единицы. Например, askYOrNCheck() выполняет 2 действия: проверяет ответ пользователя и запрашивает текст слайда. Это поможет вам яснее думать о том, что вы делаете. В-третьих, рассмотрите возможность пересмотра своих имен (например, askYOrNCheck должно быть checkAnswer).   -  person c1moore    schedule 13.11.2018
comment
Последний совет делает назначение функции более понятным. Первые несколько раз, когда я читал это, я предполагал, что вы собираетесь запрашивать ответ пользователя. Хотя это не решит вашу проблему, их решение поможет другим людям помочь вам и может помочь вам разобраться в том, что происходит, потому что ваша программа будет более семантически значимой и лучше определенной.   -  person c1moore    schedule 13.11.2018
comment
На самом деле вместо checkAnswer вы можете использовать что-то вроде shouldAddSlide(providedAnswer), которое возвращает true, если пользователь ввел yes или y, false, если пользователь ввел no или n, или выдает ошибку, если пользователь ввел что-то еще.   -  person c1moore    schedule 13.11.2018
comment
@c1moore Спасибо за ваши предложения, я обязательно просмотрю свой код. Однако я обнаружил проблему: я забыл закрыть строку чтения, поэтому вместо одного выдвигались 2 ответа.   -  person Arkin Solomon    schedule 13.11.2018


Ответы (1)


Необходимо добавить r5.close(). Он взял несколько входов с одного входа.

person Arkin Solomon    schedule 13.11.2018