es6 generator函数的异步编程
es6 generator函数,我们都知道asycn和await是generator函数的语法糖,那么genertaor怎么样才能实现asycn和await的功能呢?
1.thunk函数 将函数替换成一个只接受回调函数作为参数的单参数函数
/* Thunk 函数替换的不是表达式,而是多参数函数,将其替换成一个只接受回调函数作为参数的单参数函数。 */
/*
注 fn 传入的是一个函数,传入一个函数形成的方法,传入参数,最后传入callback
在经过两次函数调用后,该函数就换成一个只接受回调函数作为参数的单参数函数
*/
var thunk = function(fn) {
return function() {
let args = Array.prototype.slice.call(arguments);
return function (callback) {
args.push(callback);
return fn.apply(this,args)
}
}
}
2.generator异步编程的示例
/* 异步执行方法 */
function timeout(ms,val) {
return new Promise((res)=>{
setTimeout(()=>{
res(val)
},ms)
})
}
function *fn(){
yield timeout(2000,1)
console.log('222')
yield timeout(3000,2)
yield timeout(2000,3)
return 2;
}
使用while去让上面的generator函数自执行
/* res.value本身是个异步的promise方法,如果几个promise 有关联那么这样就不行了 */
var f = fn();
var res = f.next();
while(!res.done) {
res.value.then((val)=>{
console.log(val)
})
res = f.next();
}
在浏览器可知打印的结果,并不是顺序的,1 3 是同以事件输出的,2是最后输出的
我们也可以使用promise嵌套使其按顺序输出,但是这种并不好,因为可能不知道具体有几个yield,嵌套的方式写的不好看
var f = fn();
var res = f.next();
res.value.then((val)=>{
console.log(val)
return res = f.next().value
}).then((val)=>{
console.log(val)
return res = f.next().value
}).then((val)=>{
console.log(val)
return res = f.next().value
})
我们定义一个generator自执行器(注为什么要提thunk函数,timeout已经经过thunk类似的封装了)
/* 写一个适合generator的执行器 */
function *gn(){
let p1 = yield timeout(2000,1)
console.log(p1)
let p2 = yield timeout(3000,2)
console.log(p2)
let p3 = yield timeout(2000,3)
console.log(p3)
return 2;
}
// 按顺序输出 1 2 3
/* 传入要执行的gen */
/* 其实循环遍历所有的yeild (函数的递归)
根绝next返回值中的done判断是否执行到最后一个,
如果是最后一个则跳出去*/
function run(fn) {
var gen = fn();
function next(data) {
/* 执行gen.next 初始data为undefined */
var result = gen.next(data)
/* 如果result.done 为true 则代表执行到了gen的return,直接跳出去 */
if(result.done) {
return;
}
/* result.value 为promise */
result.value.then(val=>{
next(val)
})
}
/* 调用上一个next方法 */
next();
}
run(gn)
上述输出结构,分别是 1 2 3 ,间隔时间 2s 3s 2s
虽然已经有async和await这样的generator的语法糖了,但是我们还是需了解以下他们的本质。相信您了解了本质,掌握asycn和await更不在话下
文章参考地址,阮一峰老师的 Generator 函数的异步应用 http://es6.ruanyifeng.com/#docs/generator-async
es6 generator函数的异步编程的更多相关文章
- ES6的新特性(17)——Generator 函数的异步应用
Generator 函数的异步应用 异步编程对 JavaScript 语言太重要.Javascript 语言的执行环境是“单线程”的,如果没有异步编程,根本没法用,非卡死不可.本章主要介绍 Gener ...
- ES6学习笔记(十五)Generator函数的异步应用
1.传统方法 ES6 诞生以前,异步编程的方法,大概有下面四种. 回调函数 事件监听 发布/订阅 Promise 对象 Generator 函数将 JavaScript 异步编程带入了一个全新的阶段. ...
- js-ES6学习笔记-Generator函数的异步应用
1.ES6 诞生以前,异步编程的方法,大概有下面四种. 回调函数 事件监听 发布/订阅 Promise 对象 Generator 函数将 JavaScript 异步编程带入了一个全新的阶段. 2.所谓 ...
- 16.Generator 函数的异步应用
Generator 函数的异步应用 Generator 函数的异步应用 异步编程对 JavaScript 语言太重要.Javascript 语言的执行环境是"单线程"的,如果没有异 ...
- 17.Generator函数的异步应用
异步编程对 JavaScript 语言太重要.Javascript 语言的执行环境是“单线程”的,如果没有异步编程,根本没法用,非卡死不可. 1.传统方法 ES6 诞生以前,异步编程的方法,大概有下面 ...
- Generator 函数的异步应用
异步编程对 JavaScript 语言太重要.Javascript 语言的执行环境是“单线程”的,如果没有异步编程,根本没法用,非卡死不可.本章主要介绍 Generator 函数如何完成异步操作. 传 ...
- es6 generator函数
es6 新增了Generator函数,一种异步编程的解决方案 回顾一下,es6 提供了新的遍历方法,for of ,适用于各种数据集合,统一了遍历操作,原生支持for of 集合的数据集合有.数组,字 ...
- ES6:Generator函数(1)
Generator函数是ES6提供的一种异步编程解决方案.它会返回一个遍历器对象 function* helloWorldGenerator(){ yield “hello”; yield “worl ...
- es6 --- Generator 函数
第一部分,ES6 中的 Generator 在 ES6 出现之前,基本都是各式各样类似Promise的解决方案来处理异步操作的代码逻辑,但是 ES6 的Generator却给异步操作又提供了新的思路, ...
随机推荐
- 【BZOJ2521】 [Shoi2010]最小生成树
Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可 ...
- Android开源SlidingMenu的使用
一.SlidingMenu简介 SlidingMenu是最常用的几个开源项目之一. GitHub上的开源项目Slidingmenu提供了最佳的实现:定制灵活.各种阴影和渐变以及动画的滑动效果都不错.不 ...
- HDU1847--Good Luck in CET-4 Everybody!(SG函数)
Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此.当然,作为在考场浸润了十几载 ...
- 对AC自动机+DP题的一些汇总与一丝总结 (2)
POJ 2778 DNA Sequence (1)题意 : 给出m个病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 关键字眼:不包含,个数,长度 DP[i][j] : 表示长 ...
- EDM案例讲解:Mouth foods的EDM邮件营销
你可能没有听说过Mouth foods,它是一个美味产品的在线市场.作为一个日益增长的企业,他们知道电子邮件的重要性,因为在此之前他们通过电子邮件真正找到了企业品牌中的自我,这就是为什么他们认为电子邮 ...
- sqlalchemy.exc.InvalidRequestError: Table 'run_result' is already defined for this MetaData instance
临时解决办法: 在models文件导入db后,加上如下代码: db.metadata.clear() 但解决问题的根本之处还是在于找到,为何会声明了2次类的定义呢? 解析: table 'roles_ ...
- msyql 计划任务 备份数据库
用计划任务备份数据库 把exam库备份到家(home)目录下 [root@izuf66j5nlb2arg99viiuwz /]# mysqldump -u root -p exam > ~/ex ...
- Linux_系统进程管理
目录 目录 进程管理 进程管理的指令 查看进程ps指令 pgreppidof指令查pid lsof查看系统中的进程 nice指令修改进程的nice值 kill指令结束进程 top系统进程管理器任务管理 ...
- Delphi XE2 之 FireMonkey 入门(40) - 控件基础: TMemo
Delphi XE2 之 FireMonkey 入门(40) - 控件基础: TMemo 值得注意的变化: 1.其父类 TScrollBox 的许多特性也很有用处, 如: Memo1.UseSma ...
- Python学习之==>发送邮件
自动化测试执行完成后,需要自动发送测试报告.Python发送邮件可以使用smtplib标准模块,但该模块比较繁琐,推荐使用yagmail这个第三方模块,用法比较简单. 一.邮箱设置 1.在邮箱设置里打 ...