我需要创建一个与 Nodejs 一起使用的菜单/子菜单。
我正在使用8年前DeejayRaoul的解决方案@DeejayRaoul
问题如下:在主菜单中,我选择选项 “1 = 回调与承诺”,这将带我进入一个子菜单,在其中我选择选项 “1 = 测试回调”,但此选项会导致异步调用,导致:在子菜单选项之后,子菜单再次显示在控制台中,而无需等待异步函数的结果显示。
这是我的代码:
// helpers/util.js
export function sayHi(name) {
console.log("\n" + `---> Hi ${name}!` + "\n");
}
export function createTitleBox(title, maxLength, caracterToPrint) {
let titleBorder = caracterToPrint.repeat(maxLength);
const sideLength = (maxLength - title.length) / 2;
let newTitle = "";
newTitle = title.padStart(sideLength + title.length, " ");
newTitle = newTitle.padEnd(maxLength, " ");
console.log("\n");
console.log(titleBorder + "\n");
console.log(newTitle + "\n");
console.log(titleBorder + "\n");
console.log("\n");
}
// helpers/callback.js
import * as readline from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";
// CALLBACKS
async function procesarEntradaDelUsuario(callback) {
const rl = readline.createInterface({ input, output });
const nombre = await rl.question("What's your name (CALLBACK)? ");
rl.close();
callback(nombre);
}
export default procesarEntradaDelUsuario;
// helpers/promise.js
import * as readline from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";
// PROMISES
async function procesarEntradaDelUsuario_pro() {
const rl = readline.createInterface({ input, output });
const nombre = await rl.question("What's your last name (PROMISE)? ");
rl.close();
return Promise.resolve(nombre);
}
// procesarEntradaDelUsuario_pro().then((nombre) => saludar(nombre));
export default procesarEntradaDelUsuario_pro;
// index.js
import { sayHi, createTitleBox } from "./helpers/util.js";
let menuHandler;
// Initialize
function initialize() {
showMain();
process.stdin.setEncoding("utf8");
process.stdin.on("readable", checkMenu);
function checkMenu() {
let input = process.stdin.read();
if (input !== null) {
menuHandler(input.trim());
}
}
}
// Main
function showMain() {
console.log("\n" + "\x1b[33m Choose a number \x1b[0m" + "\n");
console.log(
"1 = Callback vs Promises" +
"\n" +
"2 = xxxxxxx" +
"\n" +
"3 = Exit" +
"\n\n" +
"Choose a number, then press ENTER:"
);
menuHandler = async function (input) {
switch (input) {
case "1":
show_callback_promises_SubMenu();
break;
case "2":
llama_promise();
break;
case "3":
process.exit();
break;
default:
showMain();
}
};
}
// Sub
function show_callback_promises_SubMenu() {
console.log("\n" + "\x1b[33m Choose a number \x1b[0m" + "\n");
console.log(
"1 = Test callbacks" +
"\n" +
"2 = Test promesa" +
"\n" +
"3 = Go back to main menu" +
"\n\n" +
"Choose a number, then press ENTER:"
);
menuHandler = async function (input) {
switch (input) {
case "1":
await use_callback();
break;
case "2":
use_promise();
break;
case "3":
showMain();
break;
default:
show_callback_promises_SubMenu();
}
};
}
initialize();
async function use_callback() {
try {
// CALLBACKS
createTitleBox("CALLBACK", 40, "-");
const moduleCallBack = await import("./helpers/callback.js");
await moduleCallBack.default(sayHi);
} catch (err) {
console.log(err);
}
}
async function use_promise() {
try {
// PROMISES
createTitleBox("PROMISES", 40, "-");
const modulePromise = await import("./helpers/promise.js");
modulePromise.default().then((nombre) => sayHi(nombre));
} catch (err) {
console.log(err);
}
}
您可以声明一个名为
isMenuSuspended
的全局变量,最初为 false
,在发送 Promise 之前将其设置为 true
,并在解决后再次将其设置为 false。
function checkMenu() {
let input = process.stdin.read();
if (input !== null && !isMenuSuspended) {
menuHandler(input.trim());
}
}