【问题标题】:Can I pass a parameter to ES6 generator function我可以将参数传递给 ES6 生成器函数吗
【发布时间】:2015-04-28 09:04:07
【问题描述】:

这是一个 ES6 生成器:

function *Gen() {
    var input1 = yield 'output1'
}

var gen = Gen()

gen.next('input1').value // return 'output1'

gen第一次调用,返回output1但是变量input1不等于传入的'input1'input的值实际上是'input2',第二次next('input2')调用

我的问题是如何访问下一次调用的input1,例如:

function *Gen() {
    var input 1 = param1
    var input2 = yield 'output1'
}

【问题讨论】:

  • 众所周知的问题。通常的解决方案是生成一个虚拟的初始值,该值被丢弃,但服务器会“播种”生成器。

标签: javascript generator ecmascript-6


【解决方案1】:

当您获得没有yields 的生成器时,您可以将值推送到(您处于生成器函数的开头)。您需要通过不带任何参数调用gen.next() 来触发生成器并到达第一个yield。此时,您可以使用yield,您可以通过gen.next('input1') 推送您的值,有效地将表达式yield 'output1' 替换为您传递给next - 'input1' 的值。然后您需要另一个yieldreturn 来为生成器的使用者提供您的自定义值。代码如下:

function *Gen() {
    var input1 = yield 'output1'
    return input1
}

var gen = Gen()

gen.next();
gen.next('input1').value // return 'input1'

【讨论】:

  • When you obtain the generator you don't have yields you can push value to (you are at the beginning of the generator function) +1
【解决方案2】:

This关于生成器的好文章回答了我的问题,input1 被扔掉了,无法访问它。这很奇怪,但却是真实的

【讨论】:

  • 请在您的答案中包含文章的相关部分,否则如果链接断开,它将不再具有任何价值。
【解决方案3】:

如果你想要一个参数化的生成器函数,你可以使用一个返回生成器的高阶函数:

function myGenerator(startFrom) {
    return (function *() {
        var i = startFrom;
        while (true) yield i++;
    })();
}

var gen = myGenerator(5);
console.log(gen.next().value) // 5
console.log(gen.next().value) // 6
console.log(gen.next().value) // 7

高阶生成器也可以使用:

function getGenerator(baseStartFrom, expStartFrom) {
    return (function *() {
        var a = baseStartFrom;
        while (true) {
          yield (function *() {
              var i = expStartFrom;
              while (true) yield Math.pow(a, i++);
          })();
          a++;
        }
    })();
}

var gen = getGenerator(2, 3);
var gen2 = gen.next().value; // generator yields powers of 2
  console.log(gen2.next().value); // 8
  console.log(gen2.next().value); // 16
  console.log(gen2.next().value); // 32
var gen3 = gen.next().value; // generator yields powers of 3
  console.log(gen3.next().value); // 27
  console.log(gen3.next().value); // 81
  console.log(gen3.next().value); // 243

样本很可能无用,但可以使用相同的方法,例如生成随机数生成器。

【讨论】:

  • 嗯?这不是高阶函数。并且可以替换为琐碎的function* myGenerator(i) { while (true) yield i++; }
  • @Bergi 你确实可以:) 不知何故我认为你不能。谢谢。 “高阶”术语有什么问题?
  • 对我来说,你的两个生成器都不符合higher-order functions的定义
  • 确实没有返回函数......可能最初是这样的。
  • 我对此表示赞同——太棒了,正是我所需要的,谢谢
【解决方案4】:

首先,让我们简单地举个例子:

function *createGenerator(input) {
    yield input
}

var generator = createGenerator('input')

console.log(
    generator
    .next()
    .value
)
// input

因此,您可以在创建时将值传递给生成器并将其拉出,但如果您已经创建了生成器,则获取值的唯一方法是通过.next 传递它。但是哪个.next

function *createGenerator() {
    const input = yield
    yield input
}

var generator = createGenerator()

console.log(
    generator
    .next('input1')
    .value
)
// undefined

console.log(
    generator
    .next('input2')
    .value
)
// input2

正如您在此示例中所见,第一个输入没有通过,但第二个输入通过。那是因为您的代码在生成器中执行到第一个 yield 然后停止。因此,您传入的第一个值将丢失,因为没有代码来评估它。

让我们看另一个例子:

function *createGenerator() {
    const input1 = yield
    const input2 = yield input1
    yield input2
}

var generator = createGenerator()

console.log(
    generator
    .next('input0')
    .value
)
// undefined

console.log(
    generator
    .next('input1')
    .value
)
// input1

console.log(
    generator
    .next('input2')
    .value
)
// input2

console.log(
    generator
    .next('input3')
    .value
)
// undefined

当您第二次调用.next 时,您评估传入的值,并继续处理代码直到下一个yield。在这种情况下,您执行 yield input,但它的左边没有任何内容,因为从技术上讲,这是 JavaScript AST 中执行的“下一行”。

【讨论】:

    【解决方案5】:

    这对我来说可以通过传递它应该返回的最大值来生成一个随机数。

    function *GenerateRandomNumber(maxNo){
        while(true){
            yield Math.floor(Math.random() * maxNo);
        }
    }
    
    let randomGenerator = GenerateRandomNumber(10);
    randomGenerator.next().value; // A random Number between 0 - 9
    

    【讨论】:

      猜你喜欢
      • 2017-05-07
      • 2016-04-29
      • 1970-01-01
      • 2014-02-15
      • 2011-02-20
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 2013-01-05
      相关资源
      最近更新 更多