如何在 Yeoman 中使用 promises 进行递归提示?

How to do a recursive prompt in Yeoman with promises?

我正在尝试弄清楚如何使用 promises 使用 yeoman 生成器执行递归提示。我正在尝试生成一个表单生成器,它首先会为表单组件请求一个名称,然后为每个输入(即:名字、姓氏、用户名等)请求一个名称(将用作 id)。我已经使用回调找到了这个问题的答案,但我想坚持承诺。下面是我到目前为止的代码以及我试图为递归做的但没有工作。感谢您提供任何帮助和建议,在此先感谢您!

const Generator = require('yeoman-generator')

const questions = [
  { type: 'input',
    name: 'name',
    message: 'What is the name of this form?',
    default: 'someForm'
  },
  {
    type: 'input',
    name: 'input',
    message: 'What is the name of the input?'
  },
  {
    type: 'confirm',
    name: 'askAgain',
    message: 'Is there another input to add?'
  }

]

module.exports = class extends Generator {


  prompting() {
    return this.prompt(questions).then((answers) => {
      if (answers.askAgain) {
        this.prompting()
      }
       this.userOptions = answers
       this.log(this.userOptions)
    })
  }

}

对于任何偶然发现这个 post 寻找答案的人来说,这就是我最终为使它起作用而做的事情。正如您在扩展生成器的表单 class 中看到的那样,我在其中有一个名为 prompting() 的方法。这是一个被 Yeoman 的循环识别为优先级的方法,并且在返回某些东西之前它不会离开这个方法。因为我要返回一个承诺,所以它会等到我的承诺完成后再继续。对于我的第一个提示,这正是我所需要的,但是对于在 prompting2 中发生的第二个提示,您可以添加

const done = this.async()

在方法的开头。这告诉 yeoman 你将要执行一些异步代码,并且在执行 done 之前不要越过包含它的方法。如果您不使用它并且在它之后的 class 中有另一个优先方法,例如 writing() 用于当您准备好生成生成的代码时,那么 yeoman 将跳过您的方法而不等待您的异步代码完成。您可以在我的方法 prompting2() 中看到,只要用户声明有另一个 name 输入,我就会递归调用它,并且它将继续这样做,直到他们说没有另一个 name 输入。我确信有更好的方法可以做到这一点,但这种方式对我来说效果很好。我希望这可以帮助任何正在寻找方法的人!

const Generator = require('yeoman-generator')

const questions = [
    { type: 'input',
      name: 'name',
      message: 'What is the name of this form?',
      default: 'someForm'
    }
]

const names = [
 {
   type: 'input',
   name: 'inputs',
   message: 'What is the name of the input?',
   default: '.input'
 },
 {
   type: 'confirm',
   name: 'another',
   message: "Is there another input?",
   default: true
 }
]

const inputs = []

class Form extends Generator {

  prompting() {
    return this.prompt(questions).then((answers) => {
      this.formName = answers.name
      this.log(this.formName)
   })
  }

  prompting2 () {
     const done = this.async()
     return this.prompt(names).then((answers) => {
      inputs.push(answers.inputs)
      if (answers.another) this.prompting2()
      else {
       this.inputs = inputs
       this.log(this.inputs)
       done()
      }
    })
  }

}

module.exports = Form