我们可以用 ES6 Generator 做什么而不能用 for 循环?

IT技术 javascript generator ecmascript-harmony ecmascript-6
2021-03-12 06:23:11

我了解了 ES6 的特性,而 Generators 引起了我的注意。我想到的一件事是链接 Promise 对象,而我无法用循环来做。我们将能够做哪些其他机制,而我们以前无法做到?

我确实理解这是一个广泛的问题,但目前除了 Promises 之外我想不出其他任何东西。

1个回答

通过使用yield,生成器可以在函数的控制流中的任何一点挂起,保存当前的执行状态(范围和堆栈)。

如果没有生成器,这会更复杂:

  • 您需要明确跟踪状态
  • 分支和(尤其是)循环控制结构需要以函数方式表示,即递归编写。

生成器通常用于遍历数据结构,创建一个简单的类似流的迭代器,按顺序生成所有元素。对于简单的示例,可以考虑树遍历或图中的 DFS/BFS。

function* traverseTree(node) {
    if (node == null) return;
    yield* traverseTree(node.left);
    yield node.value;
    yield* traverseTree(node.right);
}

// vs (not sure):
function traverseTree(node) {
    var rl, l, r;
    return {
        next: function() {
            if (node == null && !r) return {done:true};
            if (!l) l = traverseTree(node.left);
            if (!(rl=l.next()).done)
                return rl;
            if (node != null) {
                var n = {value:node.value};
                node = null;
                r = traverseTree(node.right);
                return n;
            }
            return r.next();
        }
    }
}
对于生成器,您根本不需要这些选项对象。它们只是成为生成器范围内的变量。
2021-04-22 06:23:11
您能否添加代码示例,如果我需要获取状态,我通常使用传递给每个并发调用自身的选项对象,这会有什么不同?
2021-04-27 06:23:11
@Grimbode:查看委托收益MDNyield*文档有点像捷径for (let x of traverseTree(node.left)) yield x;
2021-04-27 06:23:11
这个例子更有意义,但我很难理解你在第一个生成器函数中调用两次的 yield* 的概念。你能更详细地解释一下它的作用吗?非常感谢。
2021-05-08 06:23:11