让 Generator 自启动
此前只是简单使用而没有真正的去研究 Generator,这次要好好折腾下这货。
异步编程
对于 jser 来说,异步非常熟悉了吧,但是真正理解异步的却不多,因为大部分人只知道回调。
随着js的快速发展,异步方案也层出不穷,从最开始的回调到Promise,再到Generator,然后到async/await。
甚至有人说 async/await 是异步的终极解决方案,我不敢直接赞同,只能说是目前最好的异步体验。
本篇先从 Generator 讲起,后序再详细说 async/await。
从回调开始
从最最经典的 ajax 请求开始今天的话题吧。
假如,我们要依次请求 url1, url2, url3 这3个地址。
$.get('url1', function(r1) {
$.get('url2', function(r2) {
$.get('url3', function(r3) {
console.log(r1, r2, r3);
});
});
});
一不小心就写成这样了。
如果你是 jQuery 粉的话,你可能会说也可以这样实现啊。
$.get('url1').then(function(r1) {
console.log(r1);
return $.get('url2');
}).then(function(r2) {
console.log(r2);
return $.get('url3');
}).then(function(r3) {
console.log(r3);
});
用 jQuery 的 Deferred 对象,类似 Promise 来规避回调地狱,看着确实平了,但体验并不是特别友好。
用 Generator 来和谐回调
Generator 的基础这里就不展开说了,直接说应用。
function* gen() {
var r1 = yield $.get('url1');
var r2 = yield $.get('url2');
var r3 = yield $.get('url3');
console.log(r1, r2, r3);
}
这是比较友好的异步方式,但是还有个至关重要的因素,怎么运行这个 Generator 是个问题。
直接手动 g.next() 运行那肯定不行,鬼知道有多少个 yield。
我们要实现一个启动器来运行它,并把 Promise 结果传给下一次next,这样就实现了 yield 接收值的功能。
先来实现一个最简陋的起动器。
function run(gen) {
var g = gen();
function next(d) {
var r = g.next(d);
r.done || r.value.then(function(d){ next(d) }); // 这个是关键,把值传回传
}
next();
}
然后我们只要一行代码。
run(gen);
Generator 就启动起来了,并且一直执行到 done 为 true 为止。
真实例子
打开 http://www.52tian.net/ 动漫网。非广告,确实没找到合适的测试站,凑合下吧。
然后把下面代码贴到控制台,看下结果。如果执行不了,请升级浏览器,本例在 chrome 51 下通过。
function* gen() {
var r1 = yield $.get('/json/anime/4126.htm');
var r2 = yield $.get('/json/anime/11129.htm');
var r3 = yield $.get('/json/anime/427.htm');
console.log([r1, r2, r3].join('\n'));
}
function run(gen) {
var g = gen();
function next(d) {
var r = g.next(d);
r.done || r.value.then(function(d){ next(d) }); // 这个是关键,把值传回传
}
next();
}
run(gen);
小结
可能你已经发现了,其实这就是 co 的原理,但 co 比这个例子严谨多了,而且api设计的也非常友好。
本篇到此也就结束了,利用 Generator 的 yield 功能实现参数回传,让代码看起来非常‘同步’,让异步体验变的更加友好。
让 Generator 自启动的更多相关文章
- async 更优雅异步体验
上一篇<让 Generator 自启动>介绍了通过起动器让 Generator 跑起来,而本篇采用 async 实现更优雅的异步编程. 从例子开始 借用上一篇例子中的例子说起. funct ...
- linux程序自启动和新建linux服务的方法
1 linux创建自启动程序 自启动的两种方法,都经过自己测试.1.1 自启动程序方法1: 在etc/rc.local在里面加入/home/robin/code/autoruntest & ...
- EasyMesh - A Two-Dimensional Quality Mesh Generator
EasyMesh - A Two-Dimensional Quality Mesh Generator eryar@163.com Abstract. EasyMesh is developed by ...
- 轻量级“集合”迭代器-Generator
Generator是PHP 5.5加入的新语言特性.但是,它似乎并没有被很多PHP开发者广泛采用.因此,在我们了解PHP 7对Generator的改进之前,我们先通过一个简单却显而易见的例子来了解下G ...
- .NET平台开源项目速览(18)C#平台JSON实体类生成器JSON C# Class Generator
去年,我在一篇文章用原始方法解析复杂字符串,json一定要用JsonMapper么?中介绍了简单的JSON解析的问题,那种方法在当时的环境是非常方便的,因为不需要生成实体类,结构很容易解析.但随着业务 ...
- 深入解析js异步编程利器Generator
我们在编写Nodejs程序时,经常会用到回调函数,在一个操作执行完成之后对返回的数据进行处理,我简单的理解它为异步编程. 如果操作很多,那么回调的嵌套就会必不可少,那么如果操作非常多,那么回调的嵌套就 ...
- mybatis Generator生成代码及使用方式
本文原创,转载请注明:http://www.cnblogs.com/fengzheng/p/5889312.html 为什么要有mybatis mybatis 是一个 Java 的 ORM 框架,OR ...
- ABP配套代码生成器(ABP Code Generator)帮助文档,实现快速开发
ABP代码生成器介绍 针对abp这个框架做了一个代码生成器,功能强大.分为两大功能点,一个是数据层,一个是视图层. 数据服务层:通过它,可以实现表设计.领域层初始化.多语言.automapper自动注 ...
- ES6笔记(5)-- Generator生成器函数
系列文章 -- ES6笔记系列 接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还 ...
随机推荐
- crontab执行不生效-【问题篇】
背景:shell脚本每隔两分钟从数据库取数据库放到脚本所在目录,做好计划任务发现不生效. 解决:脚本中文件路径问题 测试:在/data/test目录下写的脚本,直接在本目录touch以分钟结尾的文件. ...
- 问题解决——开启Guest后仍无法共享打印机
==================================声明================================== 本文版权归作者所有 未经作者授权 请勿转载 保留法律追究的 ...
- 微信公众平台开发(三) 订阅事件(subscribe)处理
一.简介 新用户关注微信公众平台,将产生一个订阅事件,即subscribe事件,默认代码中没有对这一事件进行相应回复处理. 在新用户关注公众平台后,可能想知道该平台提供了哪些功能,以及怎样使用该平台, ...
- DuiLib学习笔记(二) 扩展CScrollbar属性
DuiLib学习笔记(二) 扩展CScrollbar属性 Duilib的滚动条滑块默认最小值为滚动条的高度(HScrollbar)或者宽度(VScrollbar).并且这个值默认为16.当采用系统样式 ...
- linux系统的7种运行级别
Linux系统有7个运行级别(runlevel)运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆运行级别2:多 ...
- setTimeout()与setInterval()——走马灯效果
JavaScript中的setTimeout()与setInterval()都是指延时执行某一操作. 但setInterval()指每隔指定时间执行某操作,会循环不断地执行该操作:setTimeout ...
- 入门级的按键驱动——按键驱动笔记之poll机制-异步通知-同步互斥阻塞-定时器防抖
文章对应视频的第12课,第5.6.7.8节. 在这之前还有查询方式的驱动编写,中断方式的驱动编写,这篇文章中暂时没有这些类容.但这篇文章是以这些为基础写的,前面的内容有空补上. 按键驱动——按下按键, ...
- [转]六款值得推荐的android(安卓)开源框架简介
本文转自:http://www.jb51.net/article/51052.htm .volley 项目地址 https://github.com/smanikandan14/Volley-demo ...
- 为opencv贡献代码
本文记录本人从发现bug,提交bug,到修复bug的过程.下面enjoy: 1.发现bug 由于项目需要,开发了一个视频检测demo,类似于扫一扫二维码的程序,不过不是这个程序不是扫二维码.具体实现参 ...
- CF721C. Journey[DP DAG]
C. Journey time limit per test 3 seconds memory limit per test 256 megabytes input standard input ou ...