Node.js 的多个菜单(菜单选项调用异步函数)

问题描述 投票:0回答:1

我需要创建一个与 Nodejs 一起使用的菜单/子菜单。

我正在使用8年前DeejayRaoul的解决方案@DeejayRaoul

问题如下:在主菜单中,我选择选项 “1 = 回调与承诺”,这将带我进入一个子菜单,在其中我选择选项 “1 = 测试回调”,但此选项会导致异步调用,导致:在子菜单选项之后,子菜单再次显示在控制台中,而无需等待异步函数的结果显示。

enter image description here

这是我的代码:

// 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);
  }
}
javascript node.js async-await
1个回答
0
投票

您可以声明一个名为

isMenuSuspended
的全局变量,最初为
false
,在发送 Promise 之前将其设置为
true
,并在解决后再次将其设置为 false。

  function checkMenu() {
    let input = process.stdin.read();
    if (input !== null && !isMenuSuspended) {
      menuHandler(input.trim());
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.