ES6 Generator的问题

发布于 09-01 05:13 字数 237 浏览 10 评论 0

jsvar p = function *() {
    yield "1";
    console.log(2);
}

var t = p();
var value = t.next();
t.next();
console.log(value);

为什么这里yield只有一个 却可以要调用两次next才能done呢?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

安静被遗忘2022-09-08 05:13:07

试下这几段代码的运行结果,就是@Honwhy给的结论。
1、

javascript'use strict';
function* fibonacci() {
    console.log("hello");
}
let seq = fibonacci();

2、

javascript'use strict';
function* fibonacci() {
    console.log("hello");
}
let seq = fibonacci();
seq.next();

3、

javascript'use strict';
function* fibonacci() {
    yield;
    console.log("hello");
}
let seq = fibonacci();
seq.next();
seq.next();
春花秋月2022-09-08 05:13:07

t.next()遇到yield要停止一下,第二次t.next()从上次yield的位置继续执行,这次没有yield语句,完成程序其他逻辑。

热鲨2022-09-08 05:13:07

你可以理解为第一次 next 从函数开始执行到 yield 的位置暂停。第二次 yield 从上次暂停的位置继续执行,到下次 yield 的位置暂停,或者随着函数结束而结束。所以正常情况(不提前 return)下 next 始终比 yield 会多一个。

这是 ES6 故意设计成这样的。为什么?因为这样实现遍历比较简单。这里得提一下 iterator 和 next 的返回值。在你的例子里,p() 返回的是个 iterator ,它的两次 next 的返回值分别为:

{value: "1", done: false}  // 1st
{done: true}               // 2nd

而在 ES6 里,对 iterator 做遍历(比如 for .. of)会不停地调用 iterator 的 next 方法直到某次返回值的 donetrue 。这段遍历逻辑可以近似地理解为:

for (var v, res; (res = it.next()) && !res.done;) {
  v = res.value;
  console.log(v);
}

我们可以看到当 donetrue 时根本连循环体都没有进入(更别提执行了)。这种情况下 nextyield 多一次,可以在简化遍历逻辑的同时保证循环完整走完。

想了解更多的信息,可以看看 You Don't Know JS - ES6 & Beyond

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文