首页 > 解决方案 > 我不明白为什么 displayAllTodoItems() 在这段代码中被执行了两次

问题描述

给出的代码是一个用 NodeJS 制作的控制台 Todo 应用程序,它可以存储新的 Todo 项目、显示它们并能够删除任何一个项目。我面临的问题是,当我在应用程序中添加一个新的 Todo 项目,然后在不停止程序的情况下,我尝试显示使用存储的所有 Todo 项目displayAllTodoItems(),结果显示两次。displayAllTodoItems()但是,如果我在停止应用程序一次后执行,则不会发生这种情况。谁能告诉我为什么会这样?

const fs = require('fs');
const readline = require('readline');

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

let outputData;
console.log(`Welcome to Todo app!
-----------------------------------
Press 1 to add a new Todo item.
Press 2 to display all Todo items.
Press 3 to delete a Todo item.
Press 4 to exit.`);
takeInput();

function takeInput(){
    rl.on("line", (answer) => {
        checkSwitch(answer);
    });
}

function checkSwitch(answer) {
    if(answer == "1"){
        rl.question("Give the name and description of the Todo item (separated by a comma):", (ans) => {
            let [name, description] = ans.split(",");
            addNewTodoItem(name, description);
        });   
    }
    else if(answer == "2"){
            displayAllTodoItems();
    }
    else if(answer == "3"){
        rl.question("Give the number of the Todo item to be deleted:", (ans) => {
            let number = ans;
            deleteATodoItem(number);
        });   
    }
    else if(answer == "4"){
        console.log("Program exited!")
        process.exit();
    }
    else {
        console.log("Invalid selection!")
    }
    takeInput();

}

const addNewTodoItem = (name, description) => {
    fs.readFile("todofile.txt", "UTF-8", (err) => {
        if(err){
            fs.writeFile("todofile.txt", `${name}:${description}\n`, (err) => {
                if(err){
                    console.log("The data couldn't be saved.");
                }
                else{
                    console.log("The Todo item has been saved.");
                }
            });
        }
        else {
            fs.appendFile("todofile.txt", `${name}:${description}\n`, (err) => {
                if(err){
                    console.log("The data couldn't be saved.");
                }
                else{
                    console.log("The Todo item has been saved.");
                }
            });
        }
    });   
}

const displayAllTodoItems = () => {
    let text = fs.readFileSync("todofile.txt").toString('utf-8').split("\n");
    text = text.filter(text=>text!="");
    text.forEach((element, i)=> {
        console.log(`${i+1}. ${element}`);
    })
}
const deleteATodoItem = () => console.log("Delete");

我也发布了这个问题的答案。

标签: javascriptnode.js

解决方案


似乎takeInput()内部的函数调用checkSwitch()是问题的原因。问题已解决。rl.on("line", callback)一旦takeInput()函数在程序开始时执行,就会监听新的行条目。在函数中takeInput()再次调用时,执行了两次,从而产生了问题。这是应用程序的完整和更正版本:checkSwitch()rl.on("line", callback)

const fs = require('fs');
const readline = require('readline');

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

let outputData;
console.log(`Welcome to Todo app!
-----------------------------------
Press 1 to add a new Todo item.
Press 2 to display all Todo items.
Press 3 to delete a Todo item.
Press 4 to exit.`);

takeInput();

function takeInput() {
    rl.on("line", (answer) => {
        checkSwitch(answer);
    });
}

function checkSwitch(answer) {
    if (answer == "1") {
        rl.question("Give the name and description of the Todo item (separated by a comma):", (ans) => {
            let [name, description] = ans.split(",");
            addNewTodoItem(name, description);
        });
    }
    else if (answer == "2") {
        displayAllTodoItems();
    }
    else if (answer == "3") {
        rl.question("Give the number of the Todo item to be deleted:", (ans) => {
            deleteATodoItem(ans);

        });
    }
    else if (answer == "4") {
        console.log("Program exited!")
        process.exit();
    }
    else {
        console.log("Invalid selection!");
    }
}

const addNewTodoItem = (name, description) => {
    fs.readFile("todofile.txt", "UTF-8", (err) => {
        if (err) {
            fs.writeFileSync("todofile.txt", `${name}:${description}\n`);
            console.log("The Todo item has been saved.");
        }
        else {
            fs.appendFile("todofile.txt", `${name}:${description}\n`, (err) => {
                if (err) {
                    console.log("The data couldn't be saved.");
                }
                else {
                    console.log("The Todo item has been saved.");
                }
            });
        }
    });
}

const displayAllTodoItems = () => {
    let text = fs.readFileSync("todofile.txt").toString('utf-8').split("\n");
    text = text.filter(text => text != "");
    text.forEach((element, i) => {
        console.log(`${i + 1}. ${element}`);
    });
}

const deleteATodoItem = (number) => {
    let text = fs.readFileSync("todofile.txt").toString('utf-8').split("\n");
    text = text.filter(text => text != "");
    text.splice(number - 1, 1);
    fs.writeFileSync("todofile.txt", text.join("\n"));
    console.log("Item deleted.");
}

推荐阅读