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却给异步操作又提供了新的思路, ...
随机推荐
- 【BZOJ2409】 地下车会
Description 小Y喜欢速度与激情,于是他参加了地下车会. 地下车会设有N 个分赛区,M种赛事.每个分赛区有C[i]场比赛.由于地下车会经营者想要赚到更多的钱,规定小 Y 必须参加某一些赛区 ...
- maven 私服的setting.xml配置
<?xml version="1.0" encoding="UTF-8"?> 2 <settings xmlns="http://m ...
- Oracle开发:dba和sysdba的区别
oracle dba和sysdba的区别如下: 1.dba是一种role对应的是对Oracle实例里对象的操作权限的集合,而sysdba是概念上的role是一种登录认证时的身份标识而已.而且,dba是 ...
- rbac权限组件整合到实际项目的全过程详述
rbac简介 项目的GitHub地址 欢迎Download&Fork&Star:https://github.com/Wanghongw/CombineRbac 另外,本文只简单介绍一 ...
- C语言:结构体中(.)和(->)的区别
https://blog.csdn.net/faihung/article/details/79190039 这虽然是个小问题,但有时候很容易让人迷惑,因为有的时候用混淆了,程序编译不通过. 下面说说 ...
- MAC安装navcat
安装及破解,参照此文: https://blog.csdn.net/marswill/article/details/79808416
- prism Callback应用
Mock<IEventAggregator> mockEventAggregator; Mock<MyEvent> mockEvent; mockEventAggregator ...
- python检测进程是否存在
import win32com.client def check_exsit(process_name): WMI = win32com.client.GetObject('winmgmts:') p ...
- Activity启动流程(三)
这里对启动Activity过程中涉及到的ActivityStack.TaskRecord.ActivityRecord.ActivityStackSupervisor进行简单的分析,实际上一张时序图就 ...
- Java面试题集(71-85)
Java程序员面试题集(71-85) 摘要:这一部分主要包括了UML(统一建模语言).面向对象的设计原则(六原则一法则).GoF设计模式.企业级设计模式.JDBC(Java数据库连接).XML(可扩展 ...