es6+最佳入门实践(10)
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)的更多相关文章
- es6+最佳入门实践(12)
12.class基础用法和继承 12.1.class基础语法 在es5中,面向对象我们通常写成这样 function Person(name,age) { this.name = name; this ...
- es6+最佳入门实践(8)
8.Promise 8.1.什么是异步? 要理解异步,首先,从同步代码开始说 alert(1) alert(2) 像上面的代码,执行顺序是从上到下,先后弹出1和2,这种代码叫做同步代码 alert(0 ...
- es6+最佳入门实践(7)
7.set和map数据结构 7.1.什么是set? Set就是集合,集合是由一组无序且唯一的项组成,在es6中新增了set这种数据结构,有点类似于数组,但是它的元素是唯一的,没有重复 let st = ...
- es6+最佳入门实践(1)
1.let和const 1.1.let和块级作用域 在es5中,js的作用域分为全局作用域和局部作用域,通常是用函数来区分的,函数内部属于局部作用域,在es6中新增了块级作用域的概念,使用{}括起来的 ...
- es6+最佳入门实践(14)
14.模版字符串 模版字符串(template string)是增强版的字符串,定义一个模版字符串需要用到反引号 let s = `这是一个模版字符串` console.log(s) 14.1.模版字 ...
- es6+最佳入门实践(13)
13.模块化 13.1.什么是模块化 模块化是一种处理复杂系统分解为更好的可管理模块的方式.通俗的讲就是把一个复杂的功能拆分成多个小功能,并且以一种良好的机制管理起来,这样就可以认为是模块化.就像作家 ...
- es6+最佳入门实践(9)
9.Iterator和for...of 9.1.Iterator是什么? Iterator又叫做迭代器,它是一种接口,为各种不同的数据结构提供统一的访问机制.这里说的接口可以形象的理解为USB接口,有 ...
- es6+最佳入门实践(6)
6.Symbol用法 6.1.什么是Symbol? Symbol是es6中一种新增加的数据类型,它表示独一无二的值.es5中我们把数据类型分为基本数据类型(字符串.数字.布尔.undefined.nu ...
- es6+最佳入门实践(5)
5.对象扩展 5.1.对象简写 在es5中,有这样一种写法 var name = "xiaoqiang"; var age = 12; var obj = { name : nam ...
随机推荐
- Moodle 3.4中添加小组、大组、群
Moodle在高中应用时经常要用到年级.班级和小组,我们可以用群.大组.小组来代替. 小组设置:网站首页-->现有课程-->右上角的设置按钮-->更多-->用户-->小组 ...
- CCS实例,网页栏目
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- 用gradle编译任意结构的Android项目
## 需求 * 继续用`Eclipse`项目的结构,但是使用`gradle`编译,或者说任意的项目结构进行编译. ## 解决方案 1. Android studio的项目结构 1. Android S ...
- BZOJ 1968 [Ahoi2005]COMMON 约数研究:数学【思维题】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1968 题意: 设f(x) = x约数的个数.如:12的约数有1,2,3,4,6,12,所以 ...
- 第二十三篇 logging模块(******)
日志非常重要,而且非常常用,可以通过logging模块实现. 热身运动 import logging logging.debug("debug message") logging. ...
- 一些排序算法的Python实现
''' Created on 2016/12/16 Created by freeol.cn 一些排序算法的Python实现 @author: 拽拽绅士 ''' '''值交换''' def swap( ...
- BZOJ 1923 SDOI2010 外星千足虫 异或方程组+bitset
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1923 懒得贴题目了......这就是解一个异或方程组的裸题...... YY了一下异或方程 ...
- POJ 2168 Joke with Turtles(DP)
Description There is a famous joke-riddle for children: Three turtles are crawling along a road. One ...
- 二分图最大权匹配:Kuhn-Munkres算法
http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646535.html
- UnrealEngine4入门(二) 实现一个可用按键控制的球体
源码摘自官网guide,加上部分自己的理解和注释 接上篇博客 本文实现一个可用WASD控制滚动的球体 先创建一个可见的球体: 在CollidingPawn.cpp的构造函数ACollidingPawn ...