在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意!

如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/学习。


generator(生成器)是ES6标准引入的新的数据类型。一个generator看上去像一个函数,但可以返回多次。

我们先看一下函数的概念:

一个函数是一段完整的代码,调用一个函数就是传入参数,然后返回结果。

function foo(x) {
return x + x;
} var r = foo(1); // 调用foo函数

在函数执行过程中,如果没有遇到 return 语句,控制权无法交回被调用的代码。(函数末尾如果没有return,就是隐含的return undefined;

generator定义

function* foo(x) {
yield x + 1;
yield x + 2;
return x + 3;
}

generator与函数的区别

generator由 function* 定义(注意多出的*号),并且,除了 return 语句,还可以用 yield 返回多次。

举个例子就容易理解了:

著名的斐波拉切数列,它是由0,1开头:

0 1 1 2 3 5 8 13 21 34 ...

要编写一个产生斐波那契数列的函数,可以这么写:

function fib(max) {
var
t,
a = 0,
b = 1,
arr = [0, 1];
while (arr.length < max) {
[a, b] = [b, a + b];
arr.push(b);
}
return arr;
} // 测试:
fib(5); // [0, 1, 1, 2, 3]
fib(10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

函数只能返回一次,所以必须返回一个Array

但是,如果换成generator,就可以一次返回一个数,不断返回多次。用generator改写如下:

'use strict'
function* fib(max) {
var
t,
a = 0,
b = 1,
n = 0;
while (n < max) {
yield a;
[a, b] = [b, a + b];
n ++;
}
return;
}

直接调用:

fib(5); // fib {[[GeneratorStatus]]: "suspended", [[GeneratorReceiver]]: Window}

我们发现,直接调用一个generator和调用函数不一样, fib(5) 仅仅是创建了一个generator对象,还没有去执行它。

调用generator对象有两个方法:

一是不断地调用generator对象的 next() 方法:

var f = fib(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: false}
f.next(); // {value: undefined, done: true}

next() 方法会执行generator的代码,然后,每次遇到 yield x; 就返回一个对象 {value: x, done: true/false} ,然后“暂停”。返回的 value 就是 yield 的返回值, done 表示这个generator是否已经执行结束了。如果 done 为 true ,则 value 就是 return 的返回值。

当执行到 done 为 true 时,这个generator对象就已经全部执行完毕,不要再继续调用 next() 了。

二是直接用 for......of 循环迭代generator对象,这种方式不需要我们自己加判断 done :

for (var x of fib(10)) {
console.log(x); // 依次输出0, 1, 1, 2, 3, ...
}

generator优点

1.正是由于generator在执行过程中能多次返回,所以它看上去像一个可以记住执行状态的函数,利用这一点,可以通过写一个generator来实现需要用面向对象才能实现的功能。

比如,用一个对象来保存状态,我们一般是用对象的属性来保存。这样很繁琐:

var fib = {
a: 0,
b: 1,
n: 0,
max: 5,
next: function () {
var
r = this.a,
t = this.a + this.b;
this.a = this.b;
this.b = t;
if (this.n < this.max) {
this.n ++;
return r;
} else {
return undefined;
}
}
};

2.generator还有另一个巨大的好处,就是把异步回调代码变成“同步”代码。

没有generator时,用AJAX时需要这么写代码:

ajax('http://url-1', data1, function (err, result) {
if (err) {
return handle(err);
}
ajax('http://url-2', data2, function (err, result) {
if (err) {
return handle(err);
}
ajax('http://url-3', data3, function (err, result) {
if (err) {
return handle(err);
}
return success(result);
});
});
});

回调越多,代码越难看。

通过使用generator时,可以这么写:

try {
r1 = yield ajax('http://url-1', data1);
r2 = yield ajax('http://url-2', data2);
r3 = yield ajax('http://url-3', data3);
success(r3);
}
catch (err) {
handle(err);
}

看上去是同步的代码,实际上是异步的代码。

JavaScript学习笔记(十三)——生成器(generator)的更多相关文章

  1. Python学习笔记014——生成器Generator

    1 生成器定义 在Python中,一边循环一边计算的机制,称之为生成器(generator). 生成器是一个迭代器. 含有yield语句的函数是生成器函数,该函数被调用时返回一个生成器对象(yield ...

  2. javascript学习笔记(四) Number 数字类型

    数字格式化方法toFixed().toExponential().toPrecision(),三个方法都四舍五入 toFixed() 方法指定小数位个数  toExponential() 方法 用科学 ...

  3. ES6学习笔记<三> 生成器函数与yield

    为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...

  4. JavaScript学习笔记[0]

    JavaScript学习笔记[0] 使用的是廖雪峰JavaScript教程. 数据类型 Number 表示数字,不区分浮点整形. === 比较时不转化数据类型. == 反之. NaN与任何值都不想等, ...

  5. python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息,抓取政府网新闻内容

    python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息PySpider:一个国人编写的强大的网络爬虫系统并带有强大的WebUI,采用Python语言编写 ...

  6. Java程序猿的JavaScript学习笔记(汇总文件夹)

    最终完结了,历时半个月. 内容包含: JavaScript面向对象特性分析,JavaScript高手必经之路. jQuery源代码级解析. jQuery EasyUI源代码级解析. Java程序猿的J ...

  7. Java程序猿的JavaScript学习笔记(8——jQuery选择器)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  8. Java程序猿JavaScript学习笔记(2——复制和继承财产)

    计划和完成在这个例子中,音符的以下序列: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaSc ...

  9. java之jvm学习笔记十三(jvm基本结构)

    java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...

  10. Java程序猿的JavaScript学习笔记(3——this/call/apply)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

随机推荐

  1. win10 UWP 发邮件

    UWP 下如何发邮件?可以使用mailto:xx?subject=*方式发送? 本文:如何在 UWP 使用默认邮件发邮件. 打开设置,应用,默认应用,选择应用 OutLook.这样就和我的一样,如果出 ...

  2. JavaScript函数之作用域 / 作用链域 / 预解析

    关于作用域和作用链域的问题,很多文章讲的都很详细,本文属于摘录自己觉得对自己有价值的部分,留由后用,仅供参考,需要查看详细信息请点击我给出的原文链接查看原文件 做一个有爱的搬运工~~ -------- ...

  3. JAVA WEB 中涉及的编解码

    1.对URL解码 1)URI部分解码:<Connector URIEncoding="UTF-8" /> 2)QueryString解码要么是 Header 中 Con ...

  4. Unix英雄传:图文细数十五位计算机先驱

    Unix,一款多任务多用户操作系统,最早由AT&T公司员工及合作伙伴在贝尔实验室于1969年开发完成.Unix的衍生及克隆版本包括Berkeley Unix.Minix.Linux.AIX.A ...

  5. js中的undefined 和null

    undefined是基本数据类型 表示未定义 缺少的意思 null是引用数据类型  是对象 表示空对象 undefined是从null派生出来的  所以undefined==null  true Ja ...

  6. 我推荐的 Java Web 学习路线

    晚上再 V2 的 Java 的节点看到有人问 Java Web 书籍推荐.我这半年多的时间,也从别的方向开始转向 Java 服务端开发,所以,我来说下我的学习路线,帮助有需要的朋友把半只脚踏进 Spr ...

  7. eclipse创建一个文件夹

    如何给eclipse创建一个文件夹,便于项目的管理:有时我们的eclipse中会有很多项目的,有的是公司的如Project1,Project2,Project3....还有的呢, 也可能是自己平时做的 ...

  8. Linux.挖矿.cpuminer方法记录

    挖矿一般都要用高端显卡做矿机, 不是一般人玩得起 这里讲的是一种用CPU来挖矿的方法, 纯玩玩, 不要指望能致富喔 本方法在CentOS和树莓派原生系统上测试通过 先从git下载cpuminer gi ...

  9. JS框架设计读书笔记之-函数

    这次写一些函数 1.模拟Object.keys方法 Object.keys = Object.keys || function(obj){ var a = []; // a[0],a[1]...分别赋 ...

  10. bug:未考虑实际使用场景

    最近bug比较多,汗颜. 1.需求背景 (1)app活动页面,用户参与并完成能够以1分钱价格购买指定商品(2)这个页面可分享至app以外的渠道,如微信.QQ等 2.这个bug的表现形式:用户在第三方渠 ...