What's the yield keyword in JavaScript?

Solution 1:

Late answering, probably everybody knows about yield now, but some better documentation has come along.

Adapting an example from "Javascript's Future: Generators" by James Long for the official Harmony standard:

function * foo(x) {
    while (true) {
        x = x * 2;
        yield x;
    }
}

"When you call foo, you get back a Generator object which has a next method."

var g = foo(2);
g.next(); // -> 4
g.next(); // -> 8
g.next(); // -> 16

So yield is kind of like return: you get something back. return x returns the value of x, but yield x returns a function, which gives you a method to iterate toward the next value. Useful if you have a potentially memory intensive procedure that you might want to interrupt during the iteration.

Solution 2:

It's Really Simple, This is how it works

  • yield keyword simply helps to pause and resume a function in any time asynchronously.
  • Additionally it helps to return value from a generator function.

Take this simple generator function:

function* process() {
    console.log('Start process 1');
    console.log('Pause process2 until call next()');

    yield;

    console.log('Resumed process2');
    console.log('Pause process3 until call next()');

    let parms = yield {age: 12};
    console.log("Passed by final process next(90): " + parms);

    console.log('Resumed process3');
    console.log('End of the process function');
}

let _process = process();

Until you call the _process.next() it wont execute the first 2 lines of code, then the first yield will pause the function. To resume the function until next pause point (yield keyword) you need to call _process.next().

You can think multiple yields are the breakpoints in a javascript debugger within a single function. Until you tell to navigate next breakpoint it wont execute the code block. (Note: without blocking the whole application)

But while yield performs this pause and resume behaviours it can return some results as well {value: any, done: boolean} according to the previous function we haven't emit any values. If we explore the previous output it will show the same { value: undefined, done: false } with value undefined.

Lets dig in to the yield keyword. Optionally you can add expression and set assign a default optional value. (Official doc syntax)

[rv] = yield [expression];

expression: Value to return from the generator function

yield any;
yield {age: 12};

rv: Returns the optional value that passed to the generator's next() method

Simply you can pass parameters to process() function with this mechanism, to execute different yield parts.

let val = yield 99; 

_process.next(10);
now the val will be 10 

Try It Now

Usages

  • Lazy evaluation
  • Infinite sequences
  • Asynchronous control flows

References:

  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield
  • http://javascript.tutorialhorizon.com/2015/09/16/generators-and-yield-in-es6/
  • https://strongloop.com/strongblog/how-to-generators-node-js-yield-use-cases/

Solution 3:

The MDN documentation is pretty good, IMO.

The function containing the yield keyword is a generator. When you call it, its formal parameters are bound to actual arguments, but its body isn't actually evaluated. Instead, a generator-iterator is returned. Each call to the generator-iterator's next() method performs another pass through the iterative algorithm. Each step's value is the value specified by the yield keyword. Think of yield as the generator-iterator version of return, indicating the boundary between each iteration of the algorithm. Each time you call next(), the generator code resumes from the statement following the yield.