9

I went trough ES6 features and Generators caught my eye. One thing that sprang to mind is chaining Promise objects, that I could not do with loops. What other mechanics we will be able to do, that we could not before?

I do understand this is broad question, still I can't think of anything but Promises at the moment.

Matas Vaitkevicius
  • 58,075
  • 31
  • 238
  • 265

1 Answers1

9

By using yield, generators can be suspended at any point in the control flow of your function, saving your current state of execution (scope & stack).

Without generators, this is more complicated:

  • you need to explicitly keep track of the state
  • branching and (especially) looping control structures need to be represented in a functional way, i.e. written recursively.

Generators are generically useful for traversing data structures, creating a simple stream-like iterator that yields all elements in order. Think of tree traversal, or DFS/BFS in graphs for simple examples.

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();
        }
    }
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Could you add code example please, if I need to get state I normally use options object that I pass into each concurrent call to itself, how this would be different? – Matas Vaitkevicius May 12 '14 at 16:45
  • You don't need those options objects at all with generators. They just become variables in the scope of the generator. – Bergi May 12 '14 at 16:53
  • The example makes a lot more sense, but I have a hard time grasping the concept of yield* that you call twice in your first generator function. Could you explain a little more in detail what it does? Thanks a lot. – kemicofa ghost Sep 02 '15 at 09:12
  • 3
    @Grimbode: Have a look at [delegated yield](http://stackoverflow.com/q/17491779/1048572) or [MDN `yield*` docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*). It's a bit like a shortcut for `for (let x of traverseTree(node.left)) yield x;` – Bergi Sep 02 '15 at 10:47