10.Generator

10.1.Generator是什么?

Generator函数是ES6提供的一种异步编程解决方案。在它的内部封装了多个状态,因此,又可以理解为一种状态机,执行Generator函数后返回一个迭代器对象,使用这个迭代器对象可以遍历出Generator函数内部的状态

Generator函数和传统函数的不同点有:1 函数定义的时候,function关键字后面加“*”, 2 内部使用yield关键字定义内部状态


function* HelloGenerator() {
yield "状态1";
yield "状态2";
yield "状态3";
yield "状态4";
} let hg = HelloGenerator();
console.log(hg.next()); //{value: "状态1", done: false}
console.log(hg.next()); //{value: "状态2", done: false}
console.log(hg.next()); //{value: "状态3", done: false}
console.log(hg.next()); //{value: "状态4", done: false}
console.log(hg.next()); //{value: undefined, done: true}

Generator函数被调用后,并不会立即执行完成,而是会在遇到yield关键字后暂停,返回的也不是函数的运行结果,而是一个执行内部状态的指针对象(Iterator对象)

注意1: next方法内可以传参数,这个参数的值作为上一次状态的返回值


function* HelloGenerator() {
let result = yield "状态1";
console.log(result);
yield "状态2";
yield "状态3";
yield "状态4";
} let hg = HelloGenerator();
console.log(hg.next());
console.log(hg.next('nodeing'));

注意2: 可以使用for...of来遍历Generator内部状态


function* HelloGenerator() { yield "状态1";
yield "状态2";
yield "状态3";
yield "状态4";
} let hg = HelloGenerator(); for( let i of hg){
console.log(i);
}

注意3: 对象没有Symbol.Iterator属性,我们可以手动添加,让其具有Iterator接口

let obj = {};
function* gen() {
yield 1;
yield 2;
yield 3;
yield 4;
}
obj[Symbol.iterator] = gen; for(let a of obj){
console.log(a);
}

10.2.Generator应用

1.限制抽奖次数

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn">抽奖</button>
<input type="text" id="ipt">
<script>
let oBtn = document.getElementById('btn');
let oIpt = document.getElementById('ipt');
let start = gen(5);
let timmer = null;
oBtn.onclick = () => {
start.next();
};
function draw(count) {
clearInterval(timmer);
let num = Math.floor(Math.random() * 30);
let prize = 0; timmer = setInterval(()=>{
prize++;
if( num === prize){
clearInterval(timmer);
alert("还可以抽"+count+"次");
return;
}
oIpt.value = prize;
}, 100); } function* gen(count) {
while (count > 0){
count--;
yield draw(count);
}
}
</script>
</body>
</html>

2.异步读取文件

const fs = require('fs');

function readFile(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, (err, data) => {
if(err){
reject(err)
}else {
resolve(data)
}
})
})
} function* asyncFile() {
yield readFile('a.txt');
yield readFile('b.txt');
yield readFile('c.txt');
} let gen = asyncFile();
gen.next().value.then((data)=>{
console.log(data.toString());
return gen.next().value;
}).then((data2)=>{
console.log(data2.toString());
return gen.next().value;
}).then((data3)=>{
console.log(data3.toString()) });

如果觉得上面的写法还比较麻烦的话,我们可以引入一个co模块,让aysncFile里面的代码自动执行

const co = require('co');

function* asyncFile() {
let a = yield readFile('a.txt');
let b = yield readFile('b.txt');
let c = yield readFile('c.txt');
console.log(a.toString(), b.toString(), c.toString())
}
co(asyncFile()).then(()=>{
console.log('文件读取完成')
});

视频教程地址:http://edu.nodeing.com/course/50

es6+最佳入门实践(10)的更多相关文章

  1. es6+最佳入门实践(12)

    12.class基础用法和继承 12.1.class基础语法 在es5中,面向对象我们通常写成这样 function Person(name,age) { this.name = name; this ...

  2. es6+最佳入门实践(8)

    8.Promise 8.1.什么是异步? 要理解异步,首先,从同步代码开始说 alert(1) alert(2) 像上面的代码,执行顺序是从上到下,先后弹出1和2,这种代码叫做同步代码 alert(0 ...

  3. es6+最佳入门实践(7)

    7.set和map数据结构 7.1.什么是set? Set就是集合,集合是由一组无序且唯一的项组成,在es6中新增了set这种数据结构,有点类似于数组,但是它的元素是唯一的,没有重复 let st = ...

  4. es6+最佳入门实践(1)

    1.let和const 1.1.let和块级作用域 在es5中,js的作用域分为全局作用域和局部作用域,通常是用函数来区分的,函数内部属于局部作用域,在es6中新增了块级作用域的概念,使用{}括起来的 ...

  5. es6+最佳入门实践(14)

    14.模版字符串 模版字符串(template string)是增强版的字符串,定义一个模版字符串需要用到反引号 let s = `这是一个模版字符串` console.log(s) 14.1.模版字 ...

  6. es6+最佳入门实践(13)

    13.模块化 13.1.什么是模块化 模块化是一种处理复杂系统分解为更好的可管理模块的方式.通俗的讲就是把一个复杂的功能拆分成多个小功能,并且以一种良好的机制管理起来,这样就可以认为是模块化.就像作家 ...

  7. es6+最佳入门实践(9)

    9.Iterator和for...of 9.1.Iterator是什么? Iterator又叫做迭代器,它是一种接口,为各种不同的数据结构提供统一的访问机制.这里说的接口可以形象的理解为USB接口,有 ...

  8. es6+最佳入门实践(6)

    6.Symbol用法 6.1.什么是Symbol? Symbol是es6中一种新增加的数据类型,它表示独一无二的值.es5中我们把数据类型分为基本数据类型(字符串.数字.布尔.undefined.nu ...

  9. es6+最佳入门实践(5)

    5.对象扩展 5.1.对象简写 在es5中,有这样一种写法 var name = "xiaoqiang"; var age = 12; var obj = { name : nam ...

随机推荐

  1. python的初体验

    最近由于毕业答辩,导致一些博客没有更新,见谅,今天我们开始一些新的内容 1.python的注释 单行注释:# 多行注释: ''' 这是多行注释 我们可以在里面写很多很多的行 ''' 2.编码风格 #c ...

  2. 当应用出现 access violation at address in module时

    Delphi2010和XE10,midas是不同的版本,之前开发的两个系统,基于不同的Delphi版本,经常出现access violation at address in module错误.特别是当 ...

  3. 给apk签名

    一.签名 把apk和签名文件放在jdk bin目录下,然后在jkd bin目录下执行以下代码: jarsigner -verbose -keystore xxx.keystore -signedjar ...

  4. result returns more than one elements此种错误,解决

    场景:公司产品开发完成后,接入第三方厂商,在进行接口联调的时候出现此问题.此接口报文中的每一个数据都要进行校验,有些是与已经存入产品数据库中的数据进行对比,看是否存在. 问题:在测试中,有些测试没有问 ...

  5. 从源码安装opencv

    操作系统为Debian9,由于使用apt-get安装在/usr/lib目录下的opencv可能会造成一些项目上的头文件错误问题,所以选择了从源码安装. 选择opencv3.4.1, 进入https:/ ...

  6. ubuntu安装显卡驱动和cuda

    NVIDIA-linux.run安装后,会出现登录页面循环,解决办法是在运行命令后加入-no-opengl-files 打开nvidia x server Settings软件,显示:You do n ...

  7. 机器学习 (一) 单变量线性回归 Linear Regression with One Variable

    文章内容均来自斯坦福大学的Andrew Ng教授讲解的Machine Learning课程,本文是针对该课程的个人学习笔记,如有疏漏,请以原课程所讲述内容为准.感谢博主Rachel Zhang的个人笔 ...

  8. Java串口编程学习1-环境配置(64位Win7)

    最近在做zigbee的课程设计,需要Java实现对串口数据的读写操作. 网上找了很多代码,好像都比较过时了,直接拿来用没法跑通……QAQ……然后自己写个教程留底,如有不当之处还请各位路过的大神赐教. ...

  9. Android EditText 限制输入字符

    今天为简单的登录界面的输入框(用户名.密码框,验证码),均为EditText框,做输入限制,不能有空格,不能有一些特殊字符,不多说,直接上代码: /** * 禁止EditText输入空格 * * @p ...

  10. Unity3D - UGUI实现Tab键切换输入框、按钮(按Tab键切换高亮显示的UI)

    1.在Hierarchy面板创建能被选中的UI(Button.InputField等). 2.在Canvas上创建C#脚本 TabCutPichon. 3.编写脚本. using System.Col ...