JavaScript 生成器Generator

定义

生成器对象是由一个 generator function 返回的,并且它符合可迭代协议和迭代器协议。

语法

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

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

使用

Generator通过 next() return()throw() 三个方法返回对应值。

Generator.prototype.next()

next() 方法返回一个包含属性 done 和 value 的对象。该方法也可以通过接受一个参数用以向生成器传值。

语法:gen.next(value)

参数:value:向生成器传值

返回值:返回的对象包含两个属性:

  • done (布尔类型) - 如果迭代器超过迭代序列的末尾,则值为 true。 在这种情况下,value 可选地指定迭代器的返回值。
    如果迭代器能够生成序列中的下一个值,则值为 false。 这相当于没有完全指定 done 属性。
  • value - 迭代器返回的任意的 JavaScript 值。当 done 的值为 true 时可以忽略该值。

示例:

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 }"

向生成器传值,使用值调用 next,注意因为生成器最初没有产生任何结果,所以第一次调用没有记录任何内容。

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()

return() 方法返回给定的值并结束生成器。

语法:gen.return(value)

参数:value:需要返回的值。

返回值:返回该函数参数中给定的值。

示例:

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,因为生成器已结束。

如果对已经处于“完成”状态的生成器调用return(value),则生成器将保持在“完成”状态。如果没有提供参数,则返回对象的value属性与示例最后的.next()方法相同。如果提供了参数,则参数将被设置为返回对象的value属性的值。

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()

throw() 方法用来向生成器抛出异常,并恢复生成器的执行,返回带有 done 及 value 两个属性的对象。

语法:gen.throw(exception)

参数:exception:用于抛出的异常。

返回值:返回的对象包含两个属性:

  • done (布尔类型) - 如果迭代器超过迭代序列的末尾,则值为 true。 在这种情况下,value 可选地指定迭代器的返回值。
    如果迭代器能够生成序列中的下一个值,则值为 false。 这相当于没有完全指定 done 属性。
  • value - 迭代器返回的任意的 JavaScript 值。当 done 的值为 true 时可以忽略该值。

示例:
在生成器中使用 throw 方法向该生成器抛出一个异常,该异常通常可以通过 try…catch 块进行捕获。

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!"

使用场景

实现 Iterator,为不具备 Iterator 接口的对象提供遍历方法。

示例:{} 原生对象是不具备 Iterator 接口无法通过 for… of遍历。用 Generator 函数为其添加 Iterator 接口,使之可以遍历。

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

参考:
1.《Generator - JavaScript | MDN》;
2.《5.2 ES6 Generator 函数 | 菜鸟教程》;

猜你喜欢

转载自blog.csdn.net/Mr_Bobcp/article/details/126085046