首页 > 解决方案 > 如何在执行期间使用 rxjs 向 Inquirer JS 动态添加问题?

问题描述

我想向用户提问,而不是立即排好所有问题。

文档中提到了 rxjs,但我觉得文档中关于如何在执行提示时正确添加问题方面存在差距,或者至少它对我来说不太适用。

https://www.npmjs.com/package/inquirer#reactive-interface

在内部,Inquirer 使用 JS 响应式扩展来处理事件和异步流。

这意味着您可以利用此功能来提供更高级的流程。例如,您可以动态添加要问的问题:

var prompts = new Rx.Subject();
inquirer.prompt(prompts);

// At some point in the future, push new questions
prompts.next({
  /* question... */
});
prompts.next({
  /* question... */
});

// When you're done
prompts.complete();

并且使用返回值过程属性,您可以访问更细粒度的回调:

inquirer.prompt(prompts).ui.process.subscribe(onEachAnswer, onError, onComplete);

标签: javascriptrxjsinquirerinquirerjs

解决方案


因此,感谢jana e 这篇博客文章的一些启发。beck,我编写了我需要的代码。来自 jana 的示例和提示有点过时了,由于某种原因,使用 rxjs 中的 Subject 不再起作用,至少它对我不起作用。然而,通过将发射器存储在观察者创建回调之外,这很容易解决。请记住将 rxjs 作为依赖项添加到您的项目中(与 InquirerJS 当前使用的相同,可能会有所帮助)。

const inquirer = require("inquirer");
var { Observable } = require("rxjs");

let emitter;

var prompts = Observable.create(function(e) {
  emitter = e;
  // need to start with at least one question here
  emitter.next({
    type: "list",
    name: "fruits",
    message: "What is your favorite fruit?",
    choices: [
      {
        name: "Banana"
      },
      {
        name: "Apple"
      },
      {
        name: "Pear"
      }
    ]
  });
});

let times = 0;

inquirer.prompt(prompts).ui.process.subscribe(
  q => {
    let dots = new Array(times).fill(".").join("");

    if (q.answer.toLowerCase() === "pear") {
      console.log("That's Great. I would never forget a Pear-eater.");
      emitter.complete();
    }

    emitter.next({
      type: "list",
      name: "fruits",
      message:
        "Sorry, what is your favorite fruit? I forgot, was it " +
        q.answer +
        ", or something else?",
      choices: [
        {
          name: "Uh, Banana.." + dots,
          value: "banana"
        },
        {
          name: "Uh, Apple.." + dots,
          value: "apple"
        },
        {
          name: "Pear!",
          value: "pear"
        }
      ]
    });

    times++;
  },
  error => {
    console.log("Hm, an error happened. Why?");
  },
  complete => {
    console.log("I think we are done now.");
  }
);

这个提示以及博客文章应该是您开始所需的内容。请记住,如果您愿意,您可以一次将多个问题排成队列。

完成后,您可以在emitter.complete();某个地方结束提示。


推荐阅读