什么是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:......

五分钟学会generator函数的更多相关文章

  1. [分享] 史上最简单的封装教程,五分钟学会封装系统(以封装Windows 7为例)

    [分享] 史上最简单的封装教程,五分钟学会封装系统(以封装Windows 7为例) 踏雁寻花 发表于 2015-8-23 23:31:28 https://www.itsk.com/thread-35 ...

  2. 一门能让你五分钟学会的语言-Brainfuck

    看到标题,不出意外的话,你肯定开始骂我了:**标题党,什么编程语言五分钟就能学会? 其实我本来也是不相信的,但是学过了才知道这是真的. 1.Brainfuck 看到这个小标题,不要误会,我没有骂人. ...

  3. 五分钟学会Python装饰器,看完面试不再慌

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第12篇文章,我们来看看Python装饰器. 一段囧事 差不多五年前面试的时候,我就领教过它的重要性.那时候我Pyt ...

  4. 喝咖啡写脚本,顺便再加一点点CSS语法糖 2.五分钟学会Less

    CoffeeScript + Html5 + Less这个新组合,看上去Less更容易拿下,先尝尝糖吧. Less这么小个东西,竟然要FQ,真是没有天理,简直不可理喻,先不管那么多了,那就看这个吧.h ...

  5. 五分钟学会 Kotlin 语法

    为什么使用Kotlin 项目一期在收尾了终于有时间折腾了,一个多月以来Kotlin从入门到现在,坚持用来开发的切身感受.因为语法与Java的区别挺大的一开始很想放弃,如果不是因为项目在使用,想必很少人 ...

  6. 10分钟学会Python函数基础知识

    看完本文大概需要8分钟,看完后,仔细看下代码,认真回一下,函数基本知识就OK了.最好还是把代码敲一下. 一.函数基础 简单地说,一个函数就是一组Python语句的组合,它们可以在程序中运行一次或多次运 ...

  7. 五分钟学会centos配置gitlab

    下载gitlab 亲测: centos6.5 安装依赖包: : yum install curl policycoreutils policycoreutils-python openssh-serv ...

  8. 五分钟学会悲观乐观锁-java vs mysql vs redis三种实现

    1 悲观锁乐观锁简介 乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果 ...

  9. 五分钟学会HTML5的WebSocket协议

    1.背景   很多网站为了实现推送技术,所用的技术都是Ajax轮询.轮询是在特定的的时间间隔由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器.这种传统的模式带来很明显的缺点 ...

随机推荐

  1. Effective Java读书笔记--类和接口

    1.使类和成员的可访问性最小化不指定访问级别,就是包私有.protected = 包私有 + 子类一般private不会被访问到,如果实现了Serializable,可能会泄露.反射.final集合或 ...

  2. xxl-job之实现流程任务编排思路

    背景   某一天一如既往的上班"旅途"中,我的领导在开早会的时候,说我最近没啥事,于是让我研究一下Activiti工作流引擎与Drools规则引擎,当时也不知道后边具体要做什么,管 ...

  3. 【洛谷 p3379】模板-最近公共祖先(图论--倍增算法求LCA)

    题目:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 解法:倍增. 1 #include<cstdio> 2 #include<cstdlib> 3 #include ...

  4. 2019牛客多校 Round9

    Solved:3 Rank:181 H Cutting Bamboos 这个东西好像叫整体二分 #include <bits/stdc++.h> using namespace std; ...

  5. LA3902 Network (树上dfs)

    题目链接:点击打开链接 题意:n台机器连成一个树状网络,其中叶节点是客户端,其他节点是服务器,目前有一台服务器s正在提供服务.让你在其他服务器上也安排同样的服务,使得每台客户端到最近服务器的距离不超过 ...

  6. zjnu1730 PIRAMIDA(字符串,模拟)

    Description Sample Input 6 JANJETINA 5 1 J 1 A 6 N 6 I 5 E Sample Output 1 0 2 1 1 题意:给你一个长度小于等于10^6 ...

  7. 【poj 1988】Cube Stacking(图论--带权并查集)

    题意:有N个方块,M个操作{"C x":查询方块x上的方块数:"M x y":移动方块x所在的整个方块堆到方块y所在的整个方块堆之上}.输出相应的答案. 解法: ...

  8. Caocao's Bridges HDU - 4738 找桥

    题意: 曹操在赤壁之战中被诸葛亮和周瑜打败.但他不会放弃.曹操的军队还是不擅长打水仗,所以他想出了另一个主意.他在长江上建造了许多岛屿,在这些岛屿的基础上,曹操的军队可以轻易地攻击周瑜的军队.曹操还修 ...

  9. hdu3033 I love sneakers!

    Problem Description After months of hard working, Iserlohn finally wins awesome amount of scholarshi ...

  10. Codeforces Round #671 (Div. 2) B. Stairs (递推)

    题意:一个台阶由一些单元格组成,如果一个高度为\(n\)的台阶中有\(n\)个不相邻的正方形(如图中的样例),就称这个台阶是"好台阶",现给你\(x\)个单元格,问最多能组成多少个 ...