什么是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. BGP总结(三)

    3.BGP路由汇总 在大规模的网络中,BGP路由表十分庞大,给设备造成了很大的负担,同时使发生路由振荡的几率也大大增加,影响网络的稳定性.路由聚合是将多条路由合并的机制,它通过只向对等体发送聚合后的路 ...

  2. linux-Navicat连接linux远程数据

    linux-Navicat连接linux远程数据 (一)登陆数据库 (二)创建用户用于远程连接 GRANT ALL PRIVILEGES ON *.* TO '账号'@'%' IDENTIFIED B ...

  3. Codeforces 102394I Interesting Permutation 思维

    题意: 你有一个长度为n的序列a(这个序列只能使用[1,n]区间内的数字,每个数字只能使用一次),通过a序列可以构造出来三个相同长度的序列f.g.h For each 1≤i≤n, fi=max{a1 ...

  4. hdu5365Shortest Path (floyd)

    Problem Description There is a path graph G=(V,E) with n vertices. Vertices are numbered from 1 to n ...

  5. Codeforces Round #645 (Div. 2) C. Celex Update

    题目链接:C.Celex Update 题意: 给你如图所示的图形,问从(x1,y1)−>(x2,y2)路径上的不同的元素和的数量是多少. 题解: 从(1,1)到(3,3) 元素和的1−2−4− ...

  6. Educational Codeforces Round 88 (Rated for Div. 2) D、Yet Another Yet Another Task

    题意: 给你一个含n个数a1,a2...an的数组,你要找到一个区间[l,r],使得al+a(l+1)+...+a(r-1)+ar减去max(al,a(l+1),...,a(r-1),ar)的值尽可能 ...

  7. codeforces 86D D. Powerful array

    An array of positive integers a1, a2, ..., an is given. Let us consider its arbitrary subarray al, a ...

  8. 数字千万别用puts!

    为了图省事我好几次都习惯的用puts输出一些确定答案,比如直接puts("-1"); 每次都wa到心态崩溃才想起来数字不能用puts...

  9. Error Code: 1055.Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'userinfo.

    环境:mysql-8.0.15-winx64 问题描述: Error querying database. Cause: java.sql.SQLSyntaxErrorException: Expre ...

  10. 初学算法之dijkstra

    dijkstra的代码思想网上各路高手所述备矣.这里只是存下用邻接矩阵和邻接表实现的dijkstra.(白书代码) 邻接矩阵 1 void dijkstra(int s){ 2 int dis[s]= ...