You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Inquirer等待函数执行完毕后再发起新提问

问题描述

我用以下代码循环调用Inquirer:

function start() {
  let stop = 0; 
  const askQuestion = () => {
    inquirer
      .prompt([
        {
          type: "list",
          name: "action",
          message: "WHAT TO DO?",
          choices: ["books", "other", "exit"],
          loop: true,
        },
      ])
      .then((answers) => {
        if (stop == 0) {
          if (answers.action == "books") {
            fetchBooks();
          } else if (answers.action == "exit") {
            stop = 1;
            return;
          }
          askQuestion();
        }
      });
  };
  askQuestion();
}

start();

我的fetchBooks函数包含API调用(books数组来自独立JSON文件):

function fetchBooks() {
  var len = 0;
  var booksAll = [];
  books.forEach((book) => {
    var bookname = APICALL(book.id).then((bxk) => {
      var b = { name: book.name, short: bxk.text };
      booksAll.push(b);
      len++;
      if (len === books.length) {
        console.log(booksAll);
      }
    });
  });
}

(无需关注fetchBooks的正确性,它本身运行正常)

当前问题:选择“books”时,fetchBooks的执行与Inquirer的新提问同时进行,输出重叠。需要让Inquirer等待fetchBooks执行完毕并输出结果后,再发起新的提问。


解决方案

核心是让fetchBooks返回Promise,通过异步链式调用或async/await,确保它执行完成后再触发下一次提问。

1. 修改fetchBooks,让它返回Promise

方式一:用Promise.all简化多API调用逻辑(推荐)

function fetchBooks() {
  // 用Promise.all等待所有API调用并行完成
  return Promise.all(books.map(book => {
    return APICALL(book.id).then(bxk => {
      return { name: book.name, short: bxk.text };
    });
  })).then(booksAll => {
    console.log(booksAll);
    return booksAll; // 可选:返回结果供后续逻辑使用
  });
}

方式二:给原有逻辑套Promise外壳

如果不想改动原有的计数逻辑,可以直接用Promise包裹:

function fetchBooks() {
  return new Promise((resolve) => {
    var len = 0;
    var booksAll = [];
    books.forEach((book) => {
      APICALL(book.id).then((bxk) => {
        var b = { name: book.name, short: bxk.text };
        booksAll.push(b);
        len++;
        if (len === books.length) {
          console.log(booksAll);
          resolve(booksAll); // 执行完成后触发resolve
        }
      });
    });
  });
}

2. 修改Inquirer逻辑,等待fetchBooks完成后再提问

方式一:链式调用then

function start() {
  let stop = 0; 
  const askQuestion = () => {
    inquirer
      .prompt([
        {
          type: "list",
          name: "action",
          message: "WHAT TO DO?",
          choices: ["books", "other", "exit"],
          loop: true,
        },
      ])
      .then((answers) => {
        if (stop == 0) {
          if (answers.action == "books") {
            // 等待fetchBooks执行完成后,再发起下一次提问
            fetchBooks().then(() => {
              askQuestion();
            });
          } else if (answers.action == "exit") {
            stop = 1;
            return;
          } else {
            // 其他操作直接继续提问
            askQuestion();
          }
        }
      });
  };
  askQuestion();
}

start();

方式二:用async/await简化代码

function start() {
  let stop = 0; 
  // 把askQuestion改成async函数
  const askQuestion = async () => {
    const answers = await inquirer.prompt([
      {
        type: "list",
        name: "action",
        message: "WHAT TO DO?",
        choices: ["books", "other", "exit"],
        loop: true,
      },
    ]);
    if (stop == 0) {
      if (answers.action == "books") {
        await fetchBooks(); // 等待fetchBooks完成
        askQuestion();
      } else if (answers.action == "exit") {
        stop = 1;
        return;
      } else {
        askQuestion();
      }
    }
  };
  askQuestion();
}

start();

内容的提问来源于stack exchange,提问作者M. Uslu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 06:45:35