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. linux ln 建立软链接-- 基于dubbo-zookeeper服务的 服务jar 引用公共的 lib

    对于ln命令网上有很多的教程,这里不再复述, 其基本目的是:多个文件夹公用一个文件夹的里的文件. 其基本命令格式: ln [option] source_file dist_file (source_ ...

  2. ORB-SLAM 代码笔记(五)Frame类

    Frame类的成员变量主要包含从摄像头获取的图像的 1. 特征点信息(关键点+描述字) 2. 尺寸不变特征所用金字塔信息,这些都定义在ORBextractor对象中 3. 词袋模型参数,用于跟踪失败情 ...

  3. java字符流实现文件间的内容复制

    package com.io.demo1; import java.io.FileReader; import java.io.FileWriter; public class TestFileSTr ...

  4. 如何从“点子”落地到“执行”?—完整解析1个手游传播类mini项目的进化

    本文来自网易云社区 作者:林玮园 从点子到落地,是不确定到确定的过程,是从模糊概念到具体现实的实现过程.无论什么点子,在落地变现的过程中都会有很多疑问产生. 首先,不确定点子本身是否成立.点子的背后是 ...

  5. PostgreSQL 数据库升级

    PostgreSQL软件版本升级后,需要使用pg_upgrade迁移旧版本的数据库,具体的操作参数可以参考官方文档,在此记录一下操作过程中出现的细节问题: 新版本软件在initdb的时候要保证loca ...

  6. BZOJ 1968 [Ahoi2005]COMMON 约数研究:数学【思维题】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1968 题意: 设f(x) = x约数的个数.如:12的约数有1,2,3,4,6,12,所以 ...

  7. 在Android上Kotlin的单元测试(KAD22)

    作者:Antonio Leiva 时间:Apr 25, 2017 原文链接:https://antonioleiva.com/unit-tests-android-kotlin/ 当然,Kotlin也 ...

  8. C#故事

    C# 在腾讯的发展 <先定个小目标, 使用C# 开发的千万级应用> Xamarin 携程使用.Net技术 分布式高并发redis MQ dubbo kafka zookeeper

  9. cmd端口占用查看和关闭端口

    cmd——回车,输入netstat -ano——回车,可以查看已占用的端口,记下端口的PID,然后打开任务管理器,点查看,选择列,勾选PID确定,找到对应的PID,结束进程,如果结束不了或者结束后还不 ...

  10. WebKit资源加载和网络栈

    webkit笔记,主要来自 朱永盛 <WebKit技术内幕> 学习笔记,转载就注明原著,该书是国内仅有的Webkit内核的书籍,学习的好导师,推荐有兴趣的朋友可以购买 WebKit资源加载 ...