什么是generator函数?

常规函数只会返回一个单一值(或者不返回任何值)。 而 Generator 可以按需一个接一个地返回(“yield”)多个值。它们可与 iterable 完美配合使用,从 而可以轻松地创建数据流。

如何创建一个generator函数,代码如下:

function* generator() {
yield 1;
yield '宋远溪';
yield {name:'宋远溪'}
}

generator函数如何使用?继续往下:

function* generator() {
yield 1;
yield '宋远溪';
yield {name:'宋远溪'}
} const genFn = generator(); console.log(
genFn.next(),
genFn.next(),
genFn.next()
)
//{ value: 1, done: false } { value: '宋远溪', done: false } { value: { name: '宋远溪' }, done: false }

由代码可以观察到,与普通函数不同的是generator函数调用会返回一个生成器对象,通过调用生成器对象的next(),可以返回generator函数体中的yield的值;

并且,通过调用next()我们可以观察到,生成器对象时可迭代的!

yield 与 next 如何交互?继续往下:

function* generator() {
var name = yield "你叫什么名字?";
yield `你好${name}`; } var iterable = generator(); console.log(
iterable.next().value,
iterable.next('李焕英').value
) //你叫什么名字?你好李焕英
  1. 第一个 .next() 启动了 generator 的执行……执行到达第一个 yield 。
  2. 结果被返回到外部代码中。
  3. 第二个 .next(4) 将 4 作为第一个 yield 的结果传递回 generator 并恢复 generator 的执 行。
  4. ...以此类推

嵌套的generator,如何交换控制权,来看《JavaScript忍者秘籍第二版》的很经典的一个例子:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Generator函数</title>
</head>
<body>
<div id="box">
<form action="">
<label for="">
<input type="text">
</label>
<button>提交</button>
</form>
<p>Generator</p>
</div> <script>
var box = box || document.getElementById('box'); function* traverseTree(element) {
yield element;
element = element.firstElementChild;
while (element) {
yield* traverseTree(element);
element = element.nextElementSibling;
}
} const subTree = traverseTree(box); for (const element of subTree) {
console.log(element.nodeName);
/**
* DIV
* FORM
* LABEL
* INPUT
* BUTTON
* P
*/
}
</script>
</body>
</html>

让我们再来看一下不用生成器函数的遍历方法,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Generator函数</title>
</head>
<body>
<div id="box">
<form action="">
<label for="">
<input type="text" />
</label>
<button>提交</button>
</form>
<p>Generator</p>
</div> <script>
var box = box || document.getElementById("box"); function domTraverse(element, callback) {
callback(element);
element = element.firstElementChild;
while (element) {
domTraverse(element, callback);
element = element.nextElementSibling;
}
} domTraverse(box, (element) => {
console.log(element.nodeName);
/**
* DIV
* FORM
* LABEL
* INPUT
* BUTTON
* P
*/
});
</script>
</body>
</html>

通过这两段代码可以看出,我们通过生成器函数将生产值(HTML节点) 与消费值(for 循环打印 访问过的节点名称)的代码分隔开,使得代码解耦;

我们还可以通过generator抛出错误,代码如下:

function* generator() {
try {
var result = yield '你喜欢JavaScript吗';
if (result == '喜欢')
yield '太棒了!'
else
yield '真遗憾'
}catch(e) {
console.log('出错了!');
console.log(e);
}
} const gen = generator(); console.log(
gen.next(),
)
gen.throw(new Error('故意抛出错误!')); //出错了,Error:......

最新文章

  1. 虚拟机出现“操作文件.PhysicalDrive1失败”的解决方法
  2. 进程间通信--pipe
  3. Eclipse 各种小图标的含义
  4. AVL树模板
  5. 怎样克服 JavaScript 框架疲劳?
  6. bzoj2096
  7. nodejs 下载网页及相关资源文件
  8. javaWEB总结(9):自定义HttpServlet
  9. shell 中的特殊符号的含义
  10. 给ThinkPHP5增加验证码功能
  11. python对字符串分割和截取的方法
  12. ng-show,ng-if区别
  13. Punycode
  14. 线性表-&gt;链式存储-&gt;双向链表
  15. C#解决方案生成工具
  16. SQL判断某列中是否包含中文字符或者英文字符
  17. JS windows.open打开窗口并居中
  18. 进入一个docker容器
  19. iOS中使用RNCryptor对资源文件加密(先加密后拖进项目中)
  20. 第39次Scrum会议(12/5)【欢迎来怼】

热门文章

  1. 一条sql查出数据库某张表的所有属性
  2. Codeforces Round #673 (Div. 2) A. Copy-paste(贪心)
  3. AtCoder Beginner Contest 172
  4. Codeforces Round #345 (Div. 1) C. Table Compression (并查集)
  5. zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)
  6. poj3260 The Fewest Coins
  7. 多线程(二)多线程的基本原理+Synchronized
  8. Clipboard API
  9. HHVM的全称是&quot;HipHop for PHP&quot;,开放源代码。采用PHP许可证授权!
  10. prefetch vs preload vs prerender vs preconnect All In One