【问题标题】:Strange yield syntax in JavaScriptJavaScript 中奇怪的 yield 语法
【发布时间】:2011-10-25 04:17:45
【问题描述】:

我刚刚看了戴夫赫尔曼的非常有趣的task.js。在他的例子中,他有这样一行:

var [foo, bar] = yield join(read("foo.json"),
                                read("bar.json")).timeout(1000);

我熟悉生成器,但我不明白 yield 表达式如何计算出可以分配给 [foo, bar] 的东西。实际上我没想到表达式可以分配给任何东西,因为它与 return 基本相同。

JS 的 yield 语法似乎仍然有点缺乏记录,我找不到有关此的信息。

所以要澄清我的问题:最终分配给 foo 和 bar 的是什么?

【问题讨论】:

  • 顺便说一句,我想添加一个“taskjs”关键字,但似乎我没有足够的声誉。
  • 请记得提问:-)

标签: javascript yield taskjs


【解决方案1】:

https://developer.mozilla.org/En/New_in_JavaScript_1.7

包含 yield 关键字的函数是一个生成器。当你调用它时,它的形式参数绑定到实际参数,但它的主体实际上并没有被评估。相反,会返回一个生成器迭代器。对生成器迭代器的 next() 方法的每次调用都会通过迭代算法执行另一次传递。每个步骤的值是由 yield 关键字指定的值。将 yield 视为 return 的生成器-迭代器版本,指示算法每次迭代之间的边界。每次调用 next() 时,生成器代码都会从 yield 后面的语句中恢复。

【讨论】:

  • 我明白这一切,因为我不明白为什么 yield 语句不会出现在循环中(我希望得到迭代器风格的语义)以及为什么使用执行直接赋值无论产量如何计算。正如你所说,这就像一个回报,所以在我看来这就像在说var something = return something_else;。我从未见过这种用法,我不确定它是什么意思。
【解决方案2】:

其实相关段落在https://developer.mozilla.org/En/New_in_JavaScript_1.7下面一点:

一旦通过调用next() 方法启动生成器,您 可以使用send(),传递一个特定的值,该值将被视为 最后一个yield 的结果。然后生成器将返回操作数 随后的yield

我认为这仅在通过直接调用其方法使用生成器时才相关,而不是在循环其值时 - 循环将始终在生成器上调用 next() 而从不调用 send()

在某种程度上,生成器执行类似于协作多任务。生成器一直执行,直到找到 yield 语句。它将控制权返回给在生成器上调用next()send() 的任何人。然后调用者继续执行,直到执行下一个 next()send() 调用 - 现在生成器再次执行。每次值都可以来回传递。

这里是一个简单的例子:

function gen()
{
  var [foo, bar] = yield 1;
  console.log("Generator got: " + foo + ", " + bar);
}

// This creates a generator but doesn't run it yet
var g = gen();

// Starts generator execution until a yield statement returns a value
var result = g.next()
console.log("Received from generator: " + result);

// Continue generator execution with [2, 3] being the return value
// of the yield statement. This will throw StopIteration because the
// iterator doesn't have any more yield statements.
g.send([2, 3]);

【讨论】:

    猜你喜欢
    • 2013-09-05
    • 2023-03-26
    • 2016-01-22
    • 2014-07-08
    • 2014-10-06
    • 1970-01-01
    • 2016-03-19
    • 2013-09-27
    相关资源
    最近更新 更多