ES6 yield (yield 1)(yield 2)(yield 3)()

4
function* generatorFunction() {
  yield (yield 1)(yield 2)(yield 3)();
}
var iterator = generatorFunction();

// [1, 2, 3]
var iteratedOver = [iterator.next().value, iterator.next().value, iterator.next().value];

我不确定这是如何工作的。 yield 不返回函数引用,那么圆括号语句像 (yield 2) 是什么意思 - 它们是没有主体的箭头函数吗?它们如何使用偏应用程序调用?
我在这里缺少了一些东西,有人能解释一下吗?
更新:尝试在三个浏览器上操作,Chrome 50.0.2661.86、Safari 9.1 (50.0.2661.86)、Firefox 44.0.2,都可以正常运行。 ESFiddle 也可以无误地执行它。
评论员报告 Babel 也可以无错误地执行。
问题来源于 http://tddbin.com/#?kata=es6/language/generator/send-function,第二个 kata。

1
你的代码示例在我的电脑上无法运行。出现了“未捕获的类型错误:(中间值)不是函数”的错误提示。 - user1106925
yield 返回你传入 .next(…) 的任何内容。你很幸运只调用了 .next() 两次,否则下一次会抛出异常。 - Bergi
@Ben:是的,但这就引出了一个问题...你为什么会认为这段代码一开始就是有效的呢?你在哪里看到它的? - user1106925
@Ben:那个链接会在输出中产生错误。不过Safari很有趣。 - user1106925
@Bergi 有三个调用,实际上对应于三个“内部”yield - Ben
显示剩余4条评论
1个回答

4

我不确定这个是怎么工作的。

嗯,是的,它其实不应该工作。只是因为Babel中存在一个错误而导致它能够工作。

yield并不返回函数引用,那么类似于(yield 2)这样的括号语句是什么意思 - 它们是没有主体的箭头函数吗?如何使用部分应用程序调用它们?

不,这实际上只是标准的函数应用程序,没有任何魔法。 yield 可以 返回函数引用,并且当它返回函数引用时,它可能会工作。当它不是函数引用时,第三个 .next() 调用将抛出异常。

以下是一个可工作版本的示例:

function* generatorFunction() {
  yield (yield 1)(yield 2)(yield 3)();
}
var test = (a) => {
  console.log(a);
  return (b) => {
    console.log(b);
    return (c) => {
      console.log(c);
      return 4;
    };
  };
};
var iterator = generatorFunction();
iterator.next(); // {value: 1, done: false}
iterator.next(test); // {value: 2, done: false}
iterator.next("a"); // "a" {value: 3, done: false}
iterator.next("b"); // "b" undefined {value: 4, done: false}
iterator.next("d"); // {value: undefined, done: true}

那么这是如何工作的呢?那些嵌套/链接的yield语句最好写成:

function* generatorFunction() {
  let fn1 = yield 1;
  let a = yield 2;
  let fn2 = fn1(a);
  let b = yield 3;
  let fn3 = fn2(b);
  let res = fn3();
  let d = yield res;
  return undefined;
}

评论者报告Babel也没有错误。
那是因为babel有一个bug。如果你检查转译器输出,它实际上的行为就像。
function* generatorFunction() {
  let fn1 = yield 1;
  let a = yield 2;
  let b = yield 3;
  // these are no more executed with only 3 `next` calls
  let fn2 = fn1(a);
  let fn3 = fn2(b);
  let res = fn3();
  let d = yield res;
  return undefined;
}

有人想要报告这个 bug 吗? - Bergi
2
regeneratorBabel中提出了问题。感谢您追踪并解决了这个问题。 - loganfsmyth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接