如何使用 rxjs 在执行期间动态向 Inquirer JS 添加问题?

Wil*_*ing 7 javascript rxjs inquirer inquirerjs

我想向用户提问,但又不想立即列出所有问题。

该文档提到了 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();
Run Code Online (Sandbox Code Playgroud)

使用返回值处理属性,您可以访问更细粒度的回调:

inquirer.prompt(prompts).ui.process.subscribe(onEachAnswer, onError, onComplete);
Run Code Online (Sandbox Code Playgroud)

Wil*_*ing 6

感谢jana e 这篇博文的一些启发。贝克,我编写了我需要的代码。jana 的示例和提示有点过时,由于某种原因使用 rxjs 中的主题将不再起作用,至少它对我不起作用。然而,通过将发射器存储在观察者创建回调之外,可以很容易地解决这个问题。请记住将 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.");
  }
);
Run Code Online (Sandbox Code Playgroud)

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

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

  • 在较新的版本中,对于同一问题的新提示(*`name`*),`askAnswered: true` 是**必需的** (2认同)