JavaScript generator Generator

definition

A generator object is returned by a generator function, and it conforms to the iterable and iterator protocols.

grammar

function* gen() {
    
    
	yield 1;
	yield 2;
}

let g = gen();
// "Generator { }"

use

Generator returns the corresponding value through three methods of next() return() and throw() .

Generator.prototype.next()

The next() method returns an object with properties done and value. This method can also be used to pass values ​​to the generator by accepting a parameter.

Syntax: gen.next(value)

Parameters: value: pass a value to the generator

Return value: The returned object contains two properties:

  • done (Boolean) - true if the iterator is past the end of the iterated sequence. In this case, value optionally specifies the return value of the iterator.
    Evaluates to false if the iterator was able to generate the next value in the sequence. This is equivalent to not fully specifying the done attribute.
  • value - the arbitrary JavaScript value returned by the iterator. This value can be ignored when done is true.

Example:

function* gen() {
    
    
	let value = yield;
	yield 1;
	yield 2;
}

let g = gen(); // "Generator { }"
g.next();      // "Object { value: 1, done: false }"
g.next();      // "Object { value: 2, done: false }"
g.next();      // "Object { value: undefined, done: true }"

Pass a value to the generator, and call next with the value, noting that the first call doesn't log anything because the generator didn't produce anything initially.

function* gen() {
    
    
	while(true) {
    
    
		var value = yield null;
		console.log(value);
	}
}

let g = gen();
g.next(1);
// "{ value: null, done: false }"
g.next(2);
// 2
// "{ value: null, done: false }"

Generator.prototype.return()

The return() method returns the given value and ends the generator.

Syntax: gen.return(value)

Parameters: value: the value to be returned.

Return Value: Returns the value given in the function parameters.

Example:

function* gen() {
    
    
	yield 1;
	yield 2;
}

let g = gen();
g.next();        // { value: 1, done: false }
g.return("stop"); // { value: "stop", done: true }
g.next();        // { value: undefined, done: true },return后再调用next时value已经undefined,因为生成器已结束。

If return(value) is called on a generator that is already in the "completed" state, the generator will remain in the "completed" state. If no arguments are provided, the value property of the returned object is the same as the .next() method at the end of the example. If an argument is provided, it will be set to the value of the value property of the returned object.

function* gen() {
    
    
	yield 1;
}

var g = gen();
g.next(); // { value: 1, done: false }
g.next(); // { value: undefined, done: true }
g.return(); // { value: undefined, done: true }
g.return("done"); // { value: "done", done: true }

Generator.prototype.throw()

The throw() method is used to throw an exception to the generator, resume the execution of the generator, and return an object with two properties done and value.

Syntax: gen.throw(exception)

Parameters: exception: The exception to throw.

Return value: The returned object contains two properties:

  • done (Boolean) - true if the iterator is past the end of the iterated sequence. In this case, value optionally specifies the return value of the iterator.
    Evaluates to false if the iterator was able to generate the next value in the sequence. This is equivalent to not fully specifying the done attribute.
  • value - the arbitrary JavaScript value returned by the iterator. This value can be ignored when done is true.

Example:
Using the throw method in a generator throws an exception to the generator that would normally be caught by a try...catch block.

function* gen() {
    
    
 	while(true) {
    
    
		try {
    
    
			yield 1;
		} catch(e) {
    
    
			console.log("Error caught!");
		}
	}
}

let g = gen();
g.next(); // { value: 1, done: false }
g.throw(new Error("Something went wrong")); // "Error caught!"

scenes to be used

Implement Iterator to provide traversal methods for objects that do not have the Iterator interface.

Example: {} native objects do not have the Iterator interface and cannot be traversed through for...of. Use the Generator function to add an Iterator interface to it so that it can be traversed.

function* objectEntries(obj) {
    
    
    const propKeys = Reflect.ownKeys(obj);
    for (const propKey of propKeys) {
    
    
        yield [propKey, obj[propKey]];
    }
}
 
const myName = {
    
     first: 'Bob', last: 'CP' };
for (const [key,value] of objectEntries(myName)) {
    
    
    console.log(`${
      
      key}: ${
      
      value}`);
}
// first: Bob
// last: CP

Reference:
1. "Generator - JavaScript | MDN";
2. "5.2 ES6 Generator Function | Novice Tutorial";

Guess you like

Origin blog.csdn.net/Mr_Bobcp/article/details/126085046