为什么Inquirer的多个prompt即便不在所属方法内也会并发执行?
问题原因
你的代码触发任意prompt后其余无关prompt全部执行的核心原因是switch分支语句未添加break关键字:JavaScript的switch语句默认会在匹配到对应case后继续向下执行所有后续分支的代码,你选择单个操作后会顺序调用所有操作方法,导致所有关联的prompt全部被触发。
需修复的问题点
optionsMenu方法的switch分支每个case末尾添加break,匹配对应操作后终止分支判断addRole方法的角色名校验逻辑中,input.toLowerCase缺少方法调用括号,修正为input.toLowerCase(),否则校验逻辑会失效addRole方法中循环索引i使用了const声明,会导致迭代时报错,修正为let声明addEmp方法完成prompt交互后未调用optionsMenu返回主菜单,可按需补充该逻辑
修复后代码
class Query { constructor () { this.options = ['View All Departments', 'View All Roles', 'View All Employees', 'Add Department', 'Add Role', 'Add Employee', 'Update Employee Role'] }; optionsMenu() { inquirer.prompt({ type: 'list', message: 'What would you like to do next?', choices: this.options, name: 'userOption' }) .then((res) => { switch(res.userOption) { case 'View All Departments': this.viewDept(); break; case 'View All Roles': this.viewRoles(); break; case 'View All Employees': this.viewEmp(); break; case 'Add Department': this.addDept(); break; case 'Add Role': this.addRole(); break; case 'Add Employee': this.addEmp(); break; case 'Update Employee Role': this.updateEmp(); break; } }) } viewDept() {} viewRoles() {} viewEmp() {} async addDept() { const inquiry = await inquirer.prompt({ type: 'input', message: 'What is the name of the new department?', name: 'department' }) const newDept = new Department(inquiry.department); newDept.insertDept().then(() => { this.optionsMenu(); }); } async addRole() { // 从数据库查询可选部门,用于关联新增角色 const departments = await mysql.db.promise().query('SELECT * FROM department').then((results) => {return results[0]}); // 将部门映射为数组用于inquirer选项 const departmentChoice = departments.map(x => x.name) // 从数据库查询现有角色 const roleQuery = await mysql.db.promise().query('SELECT * FROM role').then((results) => {return results[0]}); // 将角色名映射为小写数组用于校验唯一性 const roles = roleQuery.map(x => x.title.toLowerCase()); // inquirer提示用户录入角色信息 const inquiry = await inquirer.prompt([ { type: 'input', message: 'What is the name of the role you would like to add?', name: 'role', validate: (input) => { // 校验角色名是否已存在 let lowercase = input.toLowerCase() if (roles.includes(lowercase)) { return 'Role already exists' } else { return true; } } }, { type: 'list', message: 'Which department does the role belong to?', choices: departmentChoice, name: 'department' }, { type: 'number', message: 'What is the salary of the new role?', name: 'salary' } ]) // 遍历部门数组匹配对应部门ID for(let i = 0; i < departments.length; i++) { if (Object.values(departments[i]).includes(inquiry.department)) { const newRole = new Role(inquiry.role, departments[i].id, inquiry.salary) newRole.insertRole().then(() => {this.optionsMenu()}) } } } async addEmp() { // 从数据库查询角色列表 const roleQuery = await mysql.db.promise().query('SELECT * FROM role').then((results) => {return results[0]}); // 映射为角色名数组用于inquirer选项 const roleChoice = roleQuery.map(x => x.title); // 从数据库查询员工列表 const employeeQuery = await mysql.db.promise().query('SELECT * FROM employee').then((results) => {return results[0]}); // 映射为员工姓名数组用于inquirer选项 const employeeChoice = employeeQuery.map(x => x.first_name + " " + x.last_name); // 添加无主管选项 employeeChoice.push('None'); const inquiry = await inquirer.prompt([ { type: 'input', message: "What is the employee's first name?", name: 'firstName', validate: (input) => { if (!input) { return 'First name cannot be blank.' } else { return true; } } }, { type: 'input', message: "What is the employee's last name?", name: 'lastName', validate: (input) => { if (!input) { return 'Last name cannot be blank.' } else { return true; } } }, { type: 'list', message: "Which role will the employee take?", choices: roleChoice, name: 'role' }, { type: 'list', message: "Enter the employee's manager:", choices: employeeChoice, name: 'manager' } ]) // 此处可补充插入员工数据到数据库的逻辑,完成后调用this.optionsMenu()返回主菜单 } updateEmp() {} }
内容的提问来源于stack exchange,提问作者Kevin Chewning
相关产品推荐
相关产品推荐

